首页 文章

BIML和C#SQL连接和SSIS问题的命令

提问于
浏览
0

我的数据库上有2个表,一个叫Sales.Salesperson,它是源,目标数据库是dbo.Salesperson . 我做了一个BIML,使用C#代码从源获取现有表的列表,然后将所有数据从源导入到目标,对于我的示例,我只有1个表,我在上面列出 . 在C#上,我使用SQL连接和SQL命令来获取所有表的表和模式(再次只有1,因此它可以是动态的),

问题,因为我有一个句点,对于sepearte模式和表,在我的SQL命令中,当我从BIML转到生成SSIS包时,它给我一个来自SSIS步骤EXECUTESQL DirectInput的错误消息,当我尝试截断表<#= table#> error表示“DynamicDataLoad包中的Sales.SalesPerson包含SSIS的无效字符(/:[] . = . 无效字符将替换为_”因此,我的SSIS包上出现错误

以下是以下代码的帮助:

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Packages>
        <Package Name="DynamicDataLoad" ConstraintMode ="Linear"          ProtectionLevel="DontSaveSensitive">
        <Tasks>
            <# foreach(var table in GetTables()) { #>
            <ExecuteSQL Name="Truncate Table Dest <#=table#>" ConnectionName="Target">
                **<DirectInput>Truncate Table <#=table#></DirectInput>          
            </ExecuteSQL>**
            <Dataflow Name="Load Table <#=table#>" >
                <Transformations>
                    <OleDbSource Name="Source Table" ConnectionName="Source">
                        <ExternalTableInput Table="<#=table#>" />
                    </OleDbSource>
                    <OleDbDestination Name="Destination Table" ConnectionName="Target">
                        <ExternalTableOutput Table="<#=table#>" />
                    </OleDbDestination>
                </Transformations>
            </Dataflow>
          <# } #>
        </Tasks>
    </Package>
 </Packages>
</Biml>

以下是C#部分,如果你看一下SQL命令,我把Schema然后表带回一个叫做“table”的列表,它在上面的BIML中用来列出要转换成SSIS包的所有表,这用于BIML部分称为截断,这是错误来自BIML的地方 .

<#+
List<string> GetTables() {
    List<string> tables = new List<string>();

        SqlConnection cn = new SqlConnection("Data Source=mdsdqsdev;Initial Catalog=Test;Persist Security Info=False;Integrated Security=SSPI;");
        SqlDataAdapter da = new SqlDataAdapter();
        DataSet ds = new DataSet();
        DataTable dt = new DataTable();

        string q = "Select TABLE_SCHEMA+'.'+TABLE_NAME as name from INFORMATION_SCHEMA.TABLES";

        var cmd = new SqlCommand(q);
        cmd.Connection = cn;

    try 
    {
            da.SelectCommand = cmd;

            ds.Tables.Add(new DataTable("Results"));

            if(cn.State != ConnectionState.Open)
            {
                cn.Open();
            }

            ds.Tables[0].BeginLoadData();
            da.Fill(ds,"Results");
            ds.Tables[0].EndLoadData();

            dt = ds.Tables[0];

            if(cn.State != ConnectionState.Closed)
            {
                cn.Close();
            }
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        if (cn.State != ConnectionState.Closed)
        {
            cn.Close();
        }
        cn.Dispose();
    }

    foreach (DataRow row in dt.Rows)
    {
        tables.Add(row["name"].ToString());
    }

    return tables;
}

#>

1 回答

  • 0

    该错误由 <ExecuteSQL Name="Truncate Table Dest <#=table#>" ConnectionName="Target"><Dataflow Name="Load Table <#=table#>" > 生成,因为您的表变量将采用schema.table的形式,您的数据流名称将类似于"Dataflow Foo.Bar",如果您尝试手动输入,SSDT会拒绝指定您不能这样命名 .

    解决这个特定问题要做一些像“安全”的字符串 . 低租金方法只是应用替换呼叫来交换期间的下划线 .

    <ExecuteSQL Name="Truncate Table Dest <#=table.Replace(".", "_")#>" ConnectionName="Target">
    

    更大的问题是在它们或空格中包含无效字符的表或模式 . 那将需要你用[]包装它们 . 而不是盲目地应用它们,我会用 QUOTENAME() 将该工作推送到SQL Server

    Select QUOTENAME(TABLE_SCHEMA) +'.' + QUOTENAME(TABLE_NAME) as name
    

    我发现通常将模式和表名称作为离散部分提供给我更好的服务,因为我发现连接比分割更容易 . 这使得GetTables()的签名不同 . 也许 List<KeyValuePair<string, string>> ,我不知道 .

    即便如此,当原生Biml方式约为4行代码时,你想要做到这一点 . 我有一个例子,我使用Biml到reverse engineer a specific schema的数据库,但在Biml GetDatabaseSchema上搜索将为你提供许多如何做的例子 .

相关问题