I created a SQL Server database project (VS2017) and I added a SQLCLR C# stored procedure. It's declared like this:
public static void RequestServiceToEncryptPassword(byte[] param1, out int param2, out byte[] param3)
I also have a Windows Forms application that connects to the database and I try to execute this procedure like this:
sqlCommand = new SqlCommand(procName, sqlConnection);
sqlCommand.CommandType = System.Data.CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("param1", param1).Direction = System.Data.ParameterDirection.Input;
sqlCommand.Parameters.AddWithValue("param2", int).Direction = System.Data.ParameterDirection.Output;
sqlCommand.Parameters.AddWithValue("param3", byte[]).Direction = System.Data.ParameterDirection.Output;
There's a problem with declared data type though. What is the correct way of declaring data types for SQLCLR stored procedures or getting its output parameter values?
Sql*
types, such as SqlString
, SqlInt32
, etc. All of them have a Value
property that returns the expected .NET type. For example, SqlString.Value
returns a string
, SqlInt32.Value
returns an int
, and so on.NULL
, you can test for that by checking the IsNull
boolean property that all of the Sql*
types have.byte[]
is SqlBytes
. And SqlBytes.Value
will return a byte[]
.[SqlProcedure()]
.Putting the recommendations noted above together, we get:
[SqlProcedure()] public static void RequestServiceToEncryptPassword(SqlBytes param1, out SqlInt32 param2, out SqlBytes param3) { if(.param1.IsNull) { param2 = doSomethingWithByteArray(param1;Value). }... more.... }
AddWithValue
(as mentioned by Çöđěxěŕ in a comment on the question) as it can sometimes have problems, especially with variable length types (ie strings and binaries such as VARCHAR
, VARBINARY
, etc).For the parameters, I prefer to create each parameter as an object, which makes it easy to interact with (and more readable for more maintainable code):
paramParam1 = new SqlParameter("param1", SqlDbType.VarBinary, 500); // paramParam1.Direction = ParameterDirection.Input; // Input is default / assumed paramParam1.Value = param1; sqlCommand.Parameters.Add(paramParam1); paramParam2 = new SqlParameter("param2", SqlDbType.Int); paramParam2.Direction = ParameterDirection.Output; paramParam2.Value = intVariable; sqlCommand.Parameters.Add(paramParam2);
Please note that the optional size parameter of the SqlParameter
constructor (ie the 500
for param1
):
SqlMetaData.Max
(which simply returns -1
) for the MAX
types After executing the SqlCommand
, and output parameters will have their values set, and those can be accessed by reading their Value
property. This value will likely need to be casted into a .NET type:
int returnVal = (int)paramParam2.Value;
NULL
, then you need to check for DbNull.Value
before casting it to the appropriate type.For more info on working with SQLCLR in general, please visit: SQLCLR Info
You have to map the parameters to the SqlDbType
enum, on System.Data
. So an int would map to SqlDbType.Int
for example. For the output parameters, you can get the values using for example:
sqlCommand.Parameters("param2").Value
sqlCommand.Parameters("param3").Value
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.