另一个表中的SSIS更新表值

时间:2009-07-09 16:07:20

标签: sql-server sql-server-2005 ssis

我希望每晚使用TableB的值更新TableA。现在,我正在尝试使用带有SQL的脚本任务在SSIS 2005中执行此操作。每次我尝试以这种方式进行更新时,都会出现超时错误。

在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

2 个答案:

答案 0 :(得分: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))

以下是改变了:

  • 将相关子查询转换为连接。连接会快得多,但查询优化器可能已经为您做了
  • 无需调用多行数 - 还应该帮助您更好地匹配索引。
  • 使用整数比较而不是主要联接的字符串
  • 使用日期函数而不是转换为字符串来删除时间部分,这应该快得多,反过来允许我:
  • 在您的加入中使用日期比较而不是字符串比较

答案 1 :(得分:2)

更好的方法是执行SQL任务。