C# 使用System.Data.SqlClient向调用exec sp_executesql的SQL Server存储过程传递对称密钥的正确方法

C# 使用System.Data.SqlClient向调用exec sp_executesql的SQL Server存储过程传递对称密钥的正确方法,c#,recursion,sql-server-2017,encryption-symmetric,system.data.sqlclient,C#,Recursion,Sql Server 2017,Encryption Symmetric,System.data.sqlclient,在SQL Server 2017中,我有一个由密码保护的对称密钥加密的列。在服务器上,我可以从另一个存储过程调用sp_foo,如下所示: declare @symkey_password varchar(50) = 'Where would we be without stackoverflow' exec sp_foo @id, @symkey_password 在sp_foo中,我们有: create procedure sp_foo @id int, @symkey_pass

在SQL Server 2017中,我有一个由密码保护的对称密钥加密的列。在服务器上,我可以从另一个存储过程调用
sp_foo
,如下所示:

declare @symkey_password varchar(50) = 'Where would we be without stackoverflow'
exec sp_foo @id, @symkey_password
sp_foo
中,我们有:

 create procedure sp_foo
     @id int, @symkey_password varchar(50)
 as
 begin
     set @openkey = 'open symmetric key MY_SYM_KEY decryption by password = ' + quotename(@symkey_password,'''') + ';'
     exec sp_executesql @openkey;

     select name, convert(varchar(100), decryptbykey(myencryptedcolumn)) as plaintext
     from T 
     where id = @id   

     CLOSE SYMMETRIC KEY MY_SYM_KEY;   
end
这在服务器端运行得很好

但是,在客户端,当我在
SqlCommand
中将@id和@symkey\u密码作为标准参数传递,并尝试使用
SqlDataAdapter.Fill
时:

string pass = "Where would we be.... etc etc";

var c = new SqlCommand();
c.CommandText = "sp_foo";
c.CommandType = CommandType.StoredProcedure;

c.Parameters.Add(new SqlParameter("@id",12345);
c.Parameters.Add(new SqlParameter("@symkey_password, SqlDbType.VarChar, 50);
c.Parameters["@symkey_password"].Value = pass;

var DA = new SqlAdapter(c);

DataTable T;
DA.Fill(T);
有时会出现以下错误:

超过最大存储过程、函数、触发器或视图嵌套级别(限制32)

有时我会得到这个:

密钥未使用指定的解密程序加密。“MY_SYM_key”键未打开。使用前请先打开钥匙


当存储过程调用
sp_executesql
时,在C#中调用存储过程客户端的正确方法是什么?

侧注:不应为存储过程使用
sp_
前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用
sp.
并使用其他东西作为前缀,或者根本不使用前缀!谢谢我实际上使用了“usp”,但不知道这个名字会影响性能。真是个有趣的问题。我很惊讶你不能只是参数化开放;这感觉像是一个关于竞争开/关的时间问题;非常尴尬的注意:您不应该在存储过程中使用
sp.
前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用
sp.
并使用其他东西作为前缀,或者根本不使用前缀!谢谢我实际上使用了“usp”,但不知道这个名字会影响性能。真是个有趣的问题。我很惊讶你不能只是参数化开放;这感觉像是一个关于竞争开/关的时间问题;非常尴尬