参数化 SQL 插入失败
Parameterized SQL Insert failing
我有一个 c# winform 应用程序,我正在尝试将我的插入语句转换为参数化 sql 存储过程。当我执行 ExecuteNonQuery 时,我返回 -1,但我似乎无法找出原因。
SQL 程序:
CREATE PROCEDURE CreateReceiver
-- Add the parameters for the stored procedure here
@DBNAME sysname,
@SiteID varchar(25),
@Receiver varchar(25),
@StatusID int,
@ExpDelDate Date,
@CreateDate DateTime,
@CreateUserID varchar(25),
@CreateUserName varchar(25),
@ModDate DateTime,
@ModUserName varchar(25),
@ModUserID varchar(25),
@UserField5 varchar(25)
AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = '
INSERT INTO @DBNAME (SiteId, ReceiverNumber, StatusId, ExpectedDeliveryDate, CreatedDate, CreatedUserID,
CreatedUserName, ModifiedDate, ModifiedUserID, ModifiedUserName, UserField5) VALUES (@SiteID,@Receiver,@StatusID,
@ExpDelDate,@CreateDate,@CreateUserID,@CreateUserName,@ModDate,@ModUserID,@ModUserName,@UserField5)
';
SET @sql = REPLACE(@sql, '@DBNAME', @DBNAME);
exec sp_executesql @sql,
N'@SiteID varchar(25), @Receiver varchar(25), @StatusID int, @ExpDelDate Date, @CreateDate DateTime, @CreateUserID varchar(25),
@CreateUserName varchar(25), @ModDate DateTime, @ModUserID varchar(25), @ModUserName varchar(25), @UserField5 varchar(25)',
@SiteID=@SiteID, @Receiver=@Receiver, @StatusID=@StatusID, @ExpDelDate=@ExpDelDate, @CreateDate=@CreateDate,
@CreateUserID=@CreateUserID, @CreateUserName=@CreateUserName, @ModDate=@ModDate, @ModUserID=@ModUserID,
@ModUserName=@ModUserName, @UserField5=@UserField5;
END
GO
这是调用该过程的 C# 代码:
internal static bool BuildReturnReceiver(string pReturnTrackingNumber, string pCustomer, string pSiteId, SqlArgs pSqlArgs)
{
var pwd = GetPwd();
var sqlCred = new SqlCredential(Sqluser, pwd);
var tCatalog = GetDB(pSqlArgs.sqlDB);
var sqlConnection = new SqlConnection
{
ConnectionString = $"Data Source={SqlServer};Initial Catalog=TSC-Telaid;",
Credential = sqlCred
};
var dbName = $"[{tCatalog}].dbo.[{pSqlArgs.sqlTable}]";
var tExpDelDate = CalculateDays();
var name = GetUser();
var sqlCommand = new SqlCommand
{
Connection = sqlConnection,
CommandType = CommandType.StoredProcedure,
CommandText = "CreateReceiver",
Parameters = { new SqlParameter("@DBNAME", dbName), new SqlParameter("@SiteID", pSiteId),
new SqlParameter("@Receiver", pSqlArgs.sqlFilterValue), new SqlParameter("@StatusID", 56), new SqlParameter("@ExpDelDate", tExpDelDate),
new SqlParameter("@CreateDate", DateTime.Now), new SqlParameter("@CreateUserID", WindowsIdentity.GetCurrent().Name),
new SqlParameter("@CreateUserName", name), new SqlParameter("@ModDate", DateTime.Now), new SqlParameter("@ModUserID", WindowsIdentity.GetCurrent().Name),
new SqlParameter("@ModUserName", name), new SqlParameter("@UserField5", pSqlArgs.sqlUpdateValue)},
};
try
{
sqlConnection.Open();
return sqlCommand.ExecuteNonQuery().Equals(1);
}
catch (SqlException ex)
{
MessageBox.Show(@"Error: " + ex.Message, @"Exception", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
return false;
}
finally
{
sqlConnection.Close();
}
}
--编辑--
已更正 SQL 程序:
Alter PROCEDURE CreateReceiver
-- Add the parameters for the stored procedure here
@DBNAME sysname,
@SiteID varchar(MAX),
@Receiver varchar(MAX),
@StatusID int,
@ExpDelDate Date,
@CreateDate DateTime,
@CreateUserID varchar(MAX),
@CreateUserName varchar(MAX),
@ModDate DateTime,
@ModUserName varchar(MAX),
@ModUserID varchar(MAX),
@UserField5 varchar(MAX)
AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'
INSERT INTO ' + @DBNAME + '(SiteId, ReceiverNumber, StatusId, ExpectedDeliveryDate, CreatedDate, CreatedUserID,
CreatedUserName, ModifiedDate, ModifiedUserID, ModifiedUserName, UserField5) VALUES (@SiteID,@Receiver,@StatusID,
@ExpDelDate,@CreateDate,@CreateUserID,@CreateUserName,@ModDate,@ModUserID,@ModUserName,@UserField5)
';
--SET @sql = REPLACE(@sql, '@DBNAME', @DBNAME);
exec sp_executesql @sql,
N'@SiteID varchar(MAX), @Receiver varchar(MAX), @StatusID int, @ExpDelDate Date, @CreateDate DateTime, @CreateUserID varchar(MAX),
@CreateUserName varchar(MAX), @ModDate DateTime, @ModUserID varchar(MAX), @ModUserName varchar(MAX), @UserField5 varchar(MAX)',
@SiteID=@SiteID, @Receiver=@Receiver, @StatusID=@StatusID, @ExpDelDate=@ExpDelDate, @CreateDate=@CreateDate,
@CreateUserID=@CreateUserID, @CreateUserName=@CreateUserName, @ModDate=@ModDate, @ModUserID=@ModUserID,
@ModUserName=@ModUserName, @UserField5=@UserField5;
END
GO
您不能将 table 名称作为参数传递(在本例中它被命名为@DBNAME)。
您需要将这部分作为您的查询。请注意,我还在字符串的开头添加了 N。这是为了避免从 ASCII 转换为 UNICODE 的任何陷阱。
SET @sql = N'
INSERT INTO ' + @DBNAME + '(....'
--编辑--
由于 SqlZim 指出您将 Database.schema.TableName 作为单个数据传递,因此删除了 QUOTENAME。周围的 QUOTENAME 是行不通的。
我有一个 c# winform 应用程序,我正在尝试将我的插入语句转换为参数化 sql 存储过程。当我执行 ExecuteNonQuery 时,我返回 -1,但我似乎无法找出原因。
SQL 程序:
CREATE PROCEDURE CreateReceiver
-- Add the parameters for the stored procedure here
@DBNAME sysname,
@SiteID varchar(25),
@Receiver varchar(25),
@StatusID int,
@ExpDelDate Date,
@CreateDate DateTime,
@CreateUserID varchar(25),
@CreateUserName varchar(25),
@ModDate DateTime,
@ModUserName varchar(25),
@ModUserID varchar(25),
@UserField5 varchar(25)
AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = '
INSERT INTO @DBNAME (SiteId, ReceiverNumber, StatusId, ExpectedDeliveryDate, CreatedDate, CreatedUserID,
CreatedUserName, ModifiedDate, ModifiedUserID, ModifiedUserName, UserField5) VALUES (@SiteID,@Receiver,@StatusID,
@ExpDelDate,@CreateDate,@CreateUserID,@CreateUserName,@ModDate,@ModUserID,@ModUserName,@UserField5)
';
SET @sql = REPLACE(@sql, '@DBNAME', @DBNAME);
exec sp_executesql @sql,
N'@SiteID varchar(25), @Receiver varchar(25), @StatusID int, @ExpDelDate Date, @CreateDate DateTime, @CreateUserID varchar(25),
@CreateUserName varchar(25), @ModDate DateTime, @ModUserID varchar(25), @ModUserName varchar(25), @UserField5 varchar(25)',
@SiteID=@SiteID, @Receiver=@Receiver, @StatusID=@StatusID, @ExpDelDate=@ExpDelDate, @CreateDate=@CreateDate,
@CreateUserID=@CreateUserID, @CreateUserName=@CreateUserName, @ModDate=@ModDate, @ModUserID=@ModUserID,
@ModUserName=@ModUserName, @UserField5=@UserField5;
END
GO
这是调用该过程的 C# 代码:
internal static bool BuildReturnReceiver(string pReturnTrackingNumber, string pCustomer, string pSiteId, SqlArgs pSqlArgs)
{
var pwd = GetPwd();
var sqlCred = new SqlCredential(Sqluser, pwd);
var tCatalog = GetDB(pSqlArgs.sqlDB);
var sqlConnection = new SqlConnection
{
ConnectionString = $"Data Source={SqlServer};Initial Catalog=TSC-Telaid;",
Credential = sqlCred
};
var dbName = $"[{tCatalog}].dbo.[{pSqlArgs.sqlTable}]";
var tExpDelDate = CalculateDays();
var name = GetUser();
var sqlCommand = new SqlCommand
{
Connection = sqlConnection,
CommandType = CommandType.StoredProcedure,
CommandText = "CreateReceiver",
Parameters = { new SqlParameter("@DBNAME", dbName), new SqlParameter("@SiteID", pSiteId),
new SqlParameter("@Receiver", pSqlArgs.sqlFilterValue), new SqlParameter("@StatusID", 56), new SqlParameter("@ExpDelDate", tExpDelDate),
new SqlParameter("@CreateDate", DateTime.Now), new SqlParameter("@CreateUserID", WindowsIdentity.GetCurrent().Name),
new SqlParameter("@CreateUserName", name), new SqlParameter("@ModDate", DateTime.Now), new SqlParameter("@ModUserID", WindowsIdentity.GetCurrent().Name),
new SqlParameter("@ModUserName", name), new SqlParameter("@UserField5", pSqlArgs.sqlUpdateValue)},
};
try
{
sqlConnection.Open();
return sqlCommand.ExecuteNonQuery().Equals(1);
}
catch (SqlException ex)
{
MessageBox.Show(@"Error: " + ex.Message, @"Exception", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
return false;
}
finally
{
sqlConnection.Close();
}
}
--编辑--
已更正 SQL 程序:
Alter PROCEDURE CreateReceiver
-- Add the parameters for the stored procedure here
@DBNAME sysname,
@SiteID varchar(MAX),
@Receiver varchar(MAX),
@StatusID int,
@ExpDelDate Date,
@CreateDate DateTime,
@CreateUserID varchar(MAX),
@CreateUserName varchar(MAX),
@ModDate DateTime,
@ModUserName varchar(MAX),
@ModUserID varchar(MAX),
@UserField5 varchar(MAX)
AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'
INSERT INTO ' + @DBNAME + '(SiteId, ReceiverNumber, StatusId, ExpectedDeliveryDate, CreatedDate, CreatedUserID,
CreatedUserName, ModifiedDate, ModifiedUserID, ModifiedUserName, UserField5) VALUES (@SiteID,@Receiver,@StatusID,
@ExpDelDate,@CreateDate,@CreateUserID,@CreateUserName,@ModDate,@ModUserID,@ModUserName,@UserField5)
';
--SET @sql = REPLACE(@sql, '@DBNAME', @DBNAME);
exec sp_executesql @sql,
N'@SiteID varchar(MAX), @Receiver varchar(MAX), @StatusID int, @ExpDelDate Date, @CreateDate DateTime, @CreateUserID varchar(MAX),
@CreateUserName varchar(MAX), @ModDate DateTime, @ModUserID varchar(MAX), @ModUserName varchar(MAX), @UserField5 varchar(MAX)',
@SiteID=@SiteID, @Receiver=@Receiver, @StatusID=@StatusID, @ExpDelDate=@ExpDelDate, @CreateDate=@CreateDate,
@CreateUserID=@CreateUserID, @CreateUserName=@CreateUserName, @ModDate=@ModDate, @ModUserID=@ModUserID,
@ModUserName=@ModUserName, @UserField5=@UserField5;
END
GO
您不能将 table 名称作为参数传递(在本例中它被命名为@DBNAME)。
您需要将这部分作为您的查询。请注意,我还在字符串的开头添加了 N。这是为了避免从 ASCII 转换为 UNICODE 的任何陷阱。
SET @sql = N'
INSERT INTO ' + @DBNAME + '(....'
--编辑--
由于 SqlZim 指出您将 Database.schema.TableName 作为单个数据传递,因此删除了 QUOTENAME。周围的 QUOTENAME 是行不通的。