2016-10-22 24 views
1

所以,我知道如何用C#代码中的TVP调用sp_executeSql。这意味着我可以使用ADO.Net在PowerShell中执行此操作。如何使用Invoke-Sqlcmd从Powershell脚本内的表值参数(TVP)调用sp_executeSql?

但我很好奇如何用Invoke-Sqlcmd命令做到这一点?问题是TVP值是由用户给出的,我想避免任何Sql注入的可能性。

目前,我有以下代码:

$ControlSql = @" 
SELECT ClientId,Namespace,DatabaseConnectionString 
FROM Namespace n 
JOIN DatabaseConnection dc ON n.DatabaseConnectionId = dc.DatabaseConnectionId 
WHERE Namespace IN (SELECT Value FROM @Namespaces) 
"@ 
$ControlParams = "'@Namespaces dbo.TableOfString READONLY'" 
$ControlQuery = "EXECUTE sp_executesql @stmt = $ControlSql, @params = $ControlParams, @Namespaces = $Namespaces;" 

@Namespaces = $Namespaces部分,当然是错误的。 $Namespaces是用户提供的值列表。我不知道如何从它填充@Namespaces TVP。

嗯,我这样做,但我想知道这是否是正确的方法。在将后者传递给最终的SELECT查询之前,我可以从$Namespaces中为每个和每个值生成单个INSERT INTO @Namespaces ...语句。

因此,如果$Namespaces包含1,000个条目,则生成的sql将包含1,000个参数。

这是正确的做法吗?

回答

0

您可以通过由包含值逗号分隔的CSV文件,并使用批量插入填充表值参数(TVP) 的SQL代码为:

BULK INSERT @Namespaces 
FROM 'path_to_Namespaces.txt' 
    WITH 
    ( 
    FIELDTERMINATOR =' ,', 
    ROWTERMINATOR =' \n' 
); 

修改代码以传递文件名(通过TVP传递) 以这种方式,您避免传递大尺寸的参数。

+0

太有问题 - sql服务器需要有权访问该文件。这意味着将共享设置为所有相关服务器都可见。 – mark

+0

如果相关服务器在域中工作,则可以保护每个用户的共享并使其他人看不到其他人,看看: https://thesqldude.com/2011/12/30/how-to-sql-server-bulk-插入与约束 - 委托访问被拒绝/ –

+0

他们当然可以。但它会产生配置开销。必须有一种更简单的方法,我想我已经找到了一种方法 - 我应该使用'DataTable'而不是TVP。 – mark

相关问题