2009-07-09 71 views
2

我想每晚更新來自TableB的值的TableA。現在,我正在嘗試使用腳本任務和SSIS 2005來執行此操作。每次嘗試以這種方式進行更新時,我都會遇到超時錯誤。來自另一個表的SSIS更新表值

SSIS中有更好的方法嗎?

低於當前信息:

Public Sub Main() 

    Const Component_Name As String = "Updating TableA Data" 
    Const Conn_String As String = "Data Source=DB_A;Initial Catalog=TableA;Integrated Security=SSPI;" 

    Const sql_Emp As String = "Update TableA Set Contract = c.License_No, SEIN = convert(varchar, c.Lic_Exp_Date, 101) " _ 
     & "From Server.DB_B.dbo.TableB c Inner Join TableA b on " _ 
     & "rtrim(ltrim(c.business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14)))) " _ 
     & "Where c.Lic_Exp_Date = (select Max(Lic_Exp_Date) From Server.DB_B.dbo.TableB " _ 
     & "Where rtrim(ltrim(business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))) " _ 
     & "and convert(varchar, c.Lic_Exp_Date, 101) <> convert(varchar, b.SEIN, 101)" 

    Dim con As SqlConnection = New SqlConnection(Conn_String) 

    Try 
     Dts.Log("Opening DB Connection: " & con.ConnectionString, 0, Nothing) 

     con.Open() 

     Dim duh As New SqlCommand(sql_Emp, con) 
     duh.ExecuteNonQuery() 

     con.Close() 

     Dts.Log(String.Format(Component_Name), 0, Nothing) 
     Dts.Events.FireInformation(0, Component_Name, String.Format("TableA Data Updating"), "", 0, True) 

     Dts.TaskResult = Dts.Results.Success 

    Catch ex As Exception 
     Dts.Events.FireError(0, Component_Name, ex.Message, "", 0) 
     Dts.Log("Exception detected: " & ex.ToString, 0, Nothing) 
     Dts.TaskResult = Results.Failure 

    End Try 

End Sub 

回答

3

讓我們開始通過清理,截至一點點:

Public Sub Main() 

    Const Component_Name As String = "Updating TableA Data" 
    Const Conn_String As String = "Data Source=DB_A;Initial Catalog=TableA;Integrated Security=SSPI;" 

    Const sql_Emp As String = _ 
      "UPDATE TableA" _ 
      + " SET Contract = c.License_No, SEIN = convert(varchar, c.Lic_Exp_Date, 101)" _ 
     + " FROM Server.DB_B.dbo.TableB c" _ 
     + " INNER JOIN TableA b" _ 
      + " ON rtrim(ltrim(c.business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))" _ 
     + " WHERE c.Lic_Exp_Date= (" _ 
      + " SELECT MAX(Lic_Exp_Date)" _ 
      + " FROM Server.DB_B.dbo.TableB" _ 
      + " WHERE rtrim(ltrim(business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))" _ 
      + ") AND convert(varchar, c.Lic_Exp_Date, 101) <> convert(varchar, b.SEIN, 101)" 

    Try 
     Using con As New SqlConnection(Conn_String), _ 
       cmds New SqlCommand(sql_Emp, con) 

      Dts.Log("Opening DB Connection: " & con.ConnectionString, 0, Nothing) 

      con.Open() 
      cmd.ExecuteNonQuery() 

      Dts.Log(String.Format(Component_Name), 0, Nothing) 
      Dts.Events.FireInformation(0, Component_Name, String.Format("TableA Data Updating"), "", 0, True) 
      Dts.TaskResult = Dts.Results.Success 
     End Using 

    Catch ex As Exception 
     Dts.Events.FireError(0, Component_Name, ex.Message, "", 0) 
     Dts.Log("Exception detected: " & ex.ToString, 0, Nothing) 
     Dts.TaskResult = Results.Failure 

    End Try 

End Sub 

好了,現在我可以讀它,我可以開始尋找可能被打破。幾分鐘後回來查看編輯。


好吧,現在我們來看看該查詢。我錯過了一些數據類型信息,所以我會做一些假設。請糾正任何錯誤:

  • b.Account_Key是某種數字類型,可能是int。否則,你就不需要轉換爲varchar
  • 的Lic_Exp_Date列真的是DateTime類型

的如果這些都是正確的,我認爲這會做你想做的,但做它很多快:

UPDATE TableA 
    SET Contract = c1.License_No, SEIN = DATEADD(dd,0, DATEDIFF(dd,0, c1.Lic_Exp_Date)) 
FROM TableA b 
INNER JOIN Server.DB_B.dbo.TableB c1 
    ON ISNUMERIC(c1.busines_lic) = 1 AND cast(c1.business_lic AS int) = b.Account_Key 
INNER JOIN 
    (
     SELECT business_lic, MAX(Lic_Exp_Date) AS Lic_Exp_Date 
     FROM Server.DB_B.dbo.TableB 
     GROUP BY business_lic, License_No 
    ) c2 ON c2.business_lic = c1.business_lic AND c1.Lic_Exp_Date=c2.Lic_Exp_Date 
WHERE DATEADD(dd,0, DATEDIFF(dd,0, c1.Lic_Exp_Date)) <> DATEADD(dd,0, DATEDIFF(dd,0, b.SEIN)) 

這裏是什麼改變了:

  • 打開相關子查詢轉換爲連接。連接速度會快得多,但查詢優化器可能已經爲您執行此操作了。
  • 消除調用多個每行函數的需要 - 還應該幫助您更好地與索引進行匹配。
  • 使用整數的比較,而不是字符串爲您的主加盟
  • 使用日期函數,而不是轉換爲字符串刪除時間部分,這應該是更快,反過來讓我:
  • 使用日期比較而比您的連接中的字符串比較
+0

@Joel Coehoorn:哇!這完全是SMOKES我是怎麼做到的!你是一個SQL忍者!謝謝!我也很欣賞底部的筆記。你不僅給我提供了答案,還通過教育我給我提供了有關我未來查詢/更新速度更快的信息。你真是個好人! – JFV 2009-07-09 17:11:50

2

更好的方法將是一個執行SQL任務。

+0

@John Saunders:您對使用'執行SQL任務'選項而不是'腳本任務'是正確的。這使我現有的代碼完整無超時錯誤。 +1的幫助。 – JFV 2009-07-09 17:13:48

相關問題