0

私が3台のマシンを持っているとしましょう。1つはサーバーで、他の2つはクライアントです。SQLデータベースがサーバーにインストールされており、SQLServerクライアントが他の2台のマシンにインストールされています。そのため、クライアントマシンからSQLServerサーバーデータベースに接続できます。

ここで、誰かがテーブルに対してDML操作を実行すると、トリガーが起動し、そのトリガーからユーザーのクライアントマシンのIPアドレスが別のテーブルに格納されるようにします。だから私はよく検索し、次のようなスクリプトを見つけました:

create Procedure sp_get_ip_address (@ip varchar(40) out)
as
begin
    Declare @ipLine varchar(200)
    Declare @pos int
    set nocount on
    set @ip = NULL
    Create table #temp (ipLine varchar(200))
    Insert #temp exec master..xp_cmdshell 'ipconfig'
    select @ipLine = ipLine
    from #temp
    where upper (ipLine) like '%IP ADDRESS%'
    if (isnull (@ipLine,'***') != '***')
    begin
        set @pos = CharIndex (':',@ipLine,1);
        set @ip = rtrim(ltrim(substring (@ipLine ,
        @pos + 1 ,
        len (@ipLine) - @pos)))
    end
    drop table #temp
    set nocount off
end
go

declare @ip varchar(40)
exec sp_get_ip_address @ip out
print @ip

ただし、この上記のスクリプトは、データベースがインストールされているサーバーのIPアドレスを示します。私はこのスクリプトを探していません。正常に動作する別のスクリプトを入手しました。スクリプトは次のとおりです。

CREATE FUNCTION [dbo].[GetCurrentIP] ()
RETURNS varchar(255)
AS
BEGIN
    DECLARE @IP_Address varchar(255);

    SELECT @IP_Address = client_net_address
    FROM sys.dm_exec_connections
    WHERE Session_id = @@SPID;

    Return @IP_Address;
END

SELECT dbo.GetCurrentIP()

その他のスクリプト


DECLARE @host varchar(255)
SET @host = host_name()

CREATE TABLE #Results (
Results varchar(255)
)

DECLARE @cmd varchar(260)
SET @cmd = 'ping ' + @host

INSERT INTO #Results
EXEC master..xp_cmdshell @cmd

SELECT Replace(Left(Results, CharIndex(']', Results)), 'Pinging ', '') As [client]
 , host_name() As [host_name()]
FROM   #Results
WHERE  Results LIKE 'Pinging%'

DROP TABLE #Results

--*********************************************

-- DROP trigger and/or table if they exist
IF EXISTS(SELECT 1 FROM sysobjects WHERE type = 'TR' AND name = 'myTable_InsertUpdate') BEGIN
    DROP TRIGGER myTable_InsertUpdate
END
IF EXISTS(SELECT 1 FROM sysobjects WHERE type = 'U' AND name = 'myTable') BEGIN
    DROP TABLE myTable
END

-- Create out table; note the audit fields
CREATE TABLE myTable (
id int PRIMARY KEY NOT NULL IDENTITY(1,1)
, field1           char(1)
, changed_by_ip    char(15)
, changed_by_host  char(15)
, datetime_changed datetime
)
GO

-- Create trigger for update and insert
CREATE TRIGGER myTable_InsertUpdate
ON  myTable
FOR insert, update
AS
DECLARE @ipLine varchar(255)
DECLARE @pos    int
DECLARE @ip     char(15)

-- Temporary table creation
CREATE TABLE #ip (
ipLine varchar(255)
)

-- Insert the return of ipconfig into the temp table
INSERT #ip EXEC master..xp_cmdshell 'ipconfig'

-- Find the line which contains the IP address and assign it to a variable
SET @ipLine = (
SELECT ipLine
FROM   #ip
WHERE  ipLine LIKE '%IP Address%'
)

-- If the IP address is known
IF Coalesce(@ipLine, '***') <> '***' BEGIN
    --Find the index of the colon from the END of the string
    SET @pos = CharIndex(':', Reverse(@ipLine), 1) - 1
    --Trim the IP off the end of the string
    SET @ip =  Right(@ipLine, @pos)
    --Remove any trailing or leading white space
    SET @ip  = RTrim(LTrim(@ip))
END

-- Drop the temp table
DROP TABLE #ip

-- Update the audit fields based on the value being updated
UPDATE myTable
SET    changed_by_ip  = @ip
   , datetime_changed = GetDate()
   , changed_by_host  = host_name()
WHERE  id IN (SELECT id FROM inserted)
GO

-- Insert some test values
INSERT INTO myTable (field1) VALUES ('a')
INSERT INTO myTable (field1) VALUES ('a')

-- Display initial values
SELECT * FROM myTable

-- Update one of the fields
UPDATE myTable
SET    field1 = 'b'
WHERE  id = 2

-- Display changed values.
SELECT * FROM myTable

-- Notice the change in datetime_changed where id = 2
GO

-- And finally; clean up after ourselves
DROP TRIGGER myTable_InsertUpdate
DROP TABLE myTable

これは、SQLServer2000およびSQLServer2005のインストールで機能します

  1. このGetCurrentIP()関数をトリガーから呼び出すことはできますか?

  2. GetCurrentIP()関数はすべてのSQL Serverバージョンと互換性がありますか?たとえば、SQL Server 2000

  3. ユーザーがデータベースに接続し、カスタムアプリケーションなどのサードパーティアプリケーションを介してDML操作を実行する場合、このスクリプトはクライアントIPアドレスを取得できますか?

4

1 に答える 1

0

大きな質問:)しかし、答えは本当に短いです。

  1. このGetCurrentIP()関数をトリガーから呼び出すことはできますか?

はい。この関数の代わりに、トリガー内のコードを直接使用できます。

 

  1. GetCurrentIP()関数はすべてのSQL Serverバージョンと互換性がありますか?たとえば、SQL Server 2000?

いいえ。SQLServer2005以降の場合のみ。sys.dm_exec_sessionsSQL Server 2000では利用できなかったため。SQLServerの場合は、いくつかの異なる手法を採用する必要があります。

 

  1. ユーザーがデータベースに接続し、カスタムアプリケーションなどのサードパーティアプリケーションを介してDML操作を実行する場合、このスクリプトはクライアントIPアドレスを取得できますか?

はい。クライアントアプリケーションは、サードパーティ製であろうと自家製であろうと、クライアントアプリケーションです:)SQLServerは区別されません。

于 2012-10-08T13:21:41.813 に答える