2014-08-28 114 views
0

我已經創建了一個.net控制檯應用程序,用於從計算機和/用戶收集一些基本清單信息。它通過存儲過程將此信息轉儲到SQL Server 2012數據庫中。存儲過程偶爾會執行兩次

我偶爾會在至少兩個表中出現重複記錄。

存儲過程非常簡單,當存儲過程接收到序列號(以及其他參數)時,它會在資產表中搜索序列。如果找到匹配項,則返回assetId,否則將創建一個新條目並返回新創建的assetId。同樣在該過程中,使用先前返回的assetId將日期時間條目添加到事件表中。

我開始看到的是資產表中的兩條記錄,其序號爲assetId,但具有相同的序列號。有趣的是,事件表中將有兩個記錄對應於這些assetId的每一個都具有相同的完全相同的date_time

在我們擁有的22,000多臺電腦中,這隻發生在五個序列號上,所以對我來說這不是世界末日。但是,由於這個問題,我一直對其餘數據的可靠性提出質疑。

任何想法如何發生?

存儲過程

--Create an asset row if there is not one and retrieve the id. Or just retrieve the id. 
If (select count(assetid) from asset where [email protected]) > 0 
Begin 
    set @assetid = (select top 1 assetid from asset where [email protected]) 
End 
Else 
    --Add asset to table 
    Begin 
     Insert into asset (serial, model, manufacturer) 
     values (@serial, @model, @manufacturer); 

     set @assetid = (Select SCOPE_IDENTITY()) 
    End 
    --End Asset entry 

    --Insert Audit Event record 
    Insert into auditevent (assetid, audittime, username, computername, operatingsystem) 
    values (@assetid, @audittime, @username, @computername, @operatingsystem) 

    Declare @auditeventid int = (select SCOPE_IDENTITY()) 

    --Send the ipString to the function that will convert it to a table and insert into IP Table 
    Insert into ipaddress (auditeventid, ipaddress) 
     select * 
     from CsvToTable(@auditeventid, @ipaddressvalues) 

控制檯應用程序(單線程)

Dim strExcutionCommand As String = "dbo.auditclient @computername=N'" & strComputerName & "',@modeltext=N'" & strModel & "',@serial=N'" & strSerialNumber & "',@username=N'" & strUserName & "',@manufacturertext=N'" & strManufacturer & "',@operatingsystemtext=N'" & strOperatingSystem & "',@ipaddressvalues=N'" & strNetAddress & "'" 


    Dim Inv_ConnectString As String = "Data Source=cen-support01;Initial Catalog=IT_Inventory;User Id=" & strSqlUser & ";Password=" & strSqlPw & ";" 
    Dim myConnection As SqlConnection = New SqlConnection(Inv_ConnectString) 

    Dim myCommand As SqlCommand = New SqlCommand(strExcutionCommand, myConnection) 
    myConnection.Open() 
    myCommand.ExecuteNonQuery() 
    myConnection.Close() 
+0

你爲什麼要從應用程序進行審計,即數據庫反模式? – HLGEM 2014-08-28 15:14:19

+0

我建議將'asset.assetid'作爲主鍵,以避免重複,即使其他地方存在錯誤。我還建議用'begin transaction' /'commit'包裝所有的語句。 – wdosanjos 2014-08-28 15:22:22

+0

順便說一句,我認爲問題是調用存儲過程的控制檯應用程序,或控制檯應用程序如何觸發執行。 – wdosanjos 2014-08-28 15:23:44

回答

0

這並不容易診斷這個問題沒有對如何細節一起看到代碼控制檯應用程序它運行。例如,您是否可以運行多個實例並讓2個線程同時嘗試執行相同的任務?

當存在要添加的庫存項目並查看它是否重複時,您可以通過兩次運行控制檯應用程序來測試這是否是原因。

存儲過程的邏輯似乎很好,雖然我不是有點重新寫:

IF EXISTS (SELECT 1 FROM asset WHERE [email protected]) 
    -- Create an asset row if it doesn't exist 
    BEGIN 
     SELECT @assetid = assetid FROM asset WHERE [email protected] 
    END 
ELSE 
    --Add asset to table  
    BEGIN 
     INSERT INTO asset (serial,model,manufacturer) 
     VALUES (@serial,@model,@manufacturer); 

     SELECT @assetid = SCOPE_IDENTITY() 
    END 

這是未經測試,但你應該明白我的意思。

+0

查看我上面添加的控制檯代碼。這是一個非常簡單的程序。它是單線程的,所以沒有兩次運行任何函數。它從WMI收集數據,存儲到變量並通過存儲過程保存到數據庫。 – 2014-08-29 15:49:10