c# - 在 C# 中使用输入参数执行存储过程
问题描述
我在执行为 nvarchar(128) 类型的输入参数提供字符串值的存储过程时遇到问题。有问题的参数是 'username' 。根据 proc 定义是 nvarchar(128) 请看 screenshot#2。下面是我设置参数的 C# 代码
if (StoredProcedureExists(auditStoredProc, localConnString))
{
try
{
using (SqlCommand auditCommand = new SqlCommand("sp_executesql", localConnection, tran))
{
auditCommand.CommandType = CommandType.StoredProcedure;
auditCommand.CommandTimeout = sqlCommandTimeoutFallbackValue;
auditCommand.Parameters.AddWithValue("@stmt", auditStoredProc);
var userNameParam = auditCommand.CreateParameter();
userNameParam.ParameterName = "@username";
userNameParam.SqlDbType = SqlDbType.NVarChar;
userNameParam.Value = "JQS";
auditCommand.Parameters.Add(userNameParam);
//my custom method to show what command will be executed
var commnd = CommandAsSql(auditCommand);
auditCommand.ExecuteNonQuery();
}
}
catch (Exception e)
{
}
}
代码构建的命令执行查询是
use my_db_name_here;
declare @return_value int;
exec [sp_executesql]
@stmt = 'dbo.pr_kr_AuditSetUserName',
@username = 'JQS';
select 'Return Value' = convert(varchar, @return_value);
当它执行时,我看到的异常是
'JQS 附近的语法不正确'
完整的异常消息:e = {“'JQS' 附近的语法不正确。”}
“System.Data.SqlClient.SqlException (0x80131904): 'JQS' 附近的语法不正确。\r\n 在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection,操作1 wrapCloseInAction)\r\n 在系统.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)\r\n 在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean & dataReady )\r\n
1 wrapCloseInAction)\r\n
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,字符串 resetOptionsString,Boolean isInternal,Boolean forDescribeParameterEncryption,Boolean shouldCacheForAlwaysEncrypted)\r\n
在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior, Boolean returnStream、Boolean async、Int32 超时、Task& 任务、Boolean asyncWrite、Boolean inRetry、SqlDataReader ds、Boolean describeParameterEncryptionRequest)\r\n
在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior runBehavior、Boolean returnStream、String 方法, 任务完成源1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)\r\n
1 完成,字符串方法名,布尔 sendToPipe,Int32 超时,布尔和 usedCache,布尔 asyncWrite,布尔 inRetry)\r\n 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()\r\n 在 Endpoint.JQS.Common.Processor。 C:\dev\Endpoint.JQS\Endpoint.JQS.Common\Processor.cs: 92 行中的 ProcessJob(JobQueueMessage 消息)\r\n ClientConnectionId:39dbe3e4-8b0e-4d23-8b13-2bc379313328\r\n 错误号:102 ,状态:1,等级:15"
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
注意: 错误消息中的 Ln#92 是调用 auditCommand.ExecuteNonQuery(); 的行。
解决方案
我用存储过程名称本身替换了“sp_execute_sql”。这也消除了在 @stmt 参数中传递存储的过程名称的需要。工作代码如下。
try
{
using (SqlCommand auditCommand = new SqlCommand(
auditStoredProc,
localConnection,
tran))
{
auditCommand.CommandType = CommandType.StoredProcedure;
auditCommand.CommandTimeout = sqlCommandTimeoutFallbackValue;
var userNameParam = auditCommand.CreateParameter();
userNameParam.ParameterName = "@username";
userNameParam.SqlDbType = SqlDbType.NVarChar;
userNameParam.Value = "JobQueueService";
auditCommand.Parameters.Add(userNameParam);
auditCommand.ExecuteNonQuery();
}
}
catch (Exception e)
{
Logger.Error("Error executing audit storedprocedure" + e.ToString());
}
推荐阅读
- javascript - div 不会在两次刷新之间停止自动滚动
- python - 此类是否违反单一职责原则?
- javascript - 如何在 React 中使用 React 可加载和获取组件数据(如 Next.js)进行服务器端渲染?
- c# - 如何摆脱 *.g.cs 文件的 CS4014 警告?
- sql - 需要从 nvarchar 列中选择上周
- android - 在 Android 中使用 Firebase 流式传输视频
- python - 在单行脚本中导入后使用三元运算符的语法无效
- javascript - 如何在 nuxt.js SPA 应用程序中配置不同的 .envs?
- kubernetes - Kubectl 无法在 HPA 上描述
- python - 动态 SQL 查询 Psycopg2 值问题