在C#中向动态SQL添加参数

时间:2016-05-30 12:44:02

标签: c# sql sql-server odbc

我尝试将我已知的ON DUPLICATE KEY UPDATE实现到我使用SQL Server运行的新应用程序中。由于这只能在MySQL中编写,我编写了以下代码,但在添加参数时会出现一些错误。

这些是错误消息:

ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Die @FaeBezeichnung-Skalarvariable muss deklariert werden.

ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Die @VeraendertAm-Skalarvariable muss deklariert werden.

ERROR [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Die @mitIDref-Skalarvariable muss deklariert werden.

我的代码如下所示:

STRSQL:

DECLARE @faeID AS int
begin tran
    SELECT @faeID = faeID FROM mdb_Faehigkeiten WHERE kurzBez = @FaeBezeichnung 
    UPDATE mdb_Faehigkeiten WITH (serializable)
    SET VeraendertAm = @VeraendertAm
    WHERE mitIDref = @mitIDref AND faeIDref = @faeID
    if @@rowcount = 0
    begin
        INSERT mdb_Faehigkeiten (mitIDref, faeIDref, VeraendertAm)
        VALUES (@mitIDref, @faeID, @VeraendertAm)
    end
commit tran

C#:

OdbcConnection conn = GetConnection();
OdbcCommand cmd = new OdbcCommand(strSQL, conn);
cmd.Parameters.Add("@mitIDref", OdbcType.Int).Value = dgv[0, item.iRow].Value;
cmd.Parameters.Add("@VeraendertAm", OdbcType.DateTime).Value = dgv[item.iColumn, item.iRow].Value;
cmd.Parameters.Add("@FaeBezeichnung ", OdbcType.VarChar).Value = dgv.Columns[item.iColumn].HeaderText;

try
{
    conn.Open();
    cmd.ExecuteNonQuery();
}
catch { throw; }
finally { conn.Close(); }

任何人都可以帮助我,或者基本上不可能将参数实现到动态SQL语句中?

2 个答案:

答案 0 :(得分:1)

根据MSDN

  

用于ODBC的.NET Framework数据提供程序不支持传递   命名参数到SQL语句或被调用的存储过程   通过OdbcCommand。在任何一种情况下,请使用问号(?)   占位符。

底线,而不是

DECLARE @faeID AS int
begin tran
    SELECT @faeID = faeID FROM mdb_Faehigkeiten WHERE kurzBez = @FaeBezeichnung 
    UPDATE mdb_Faehigkeiten WITH (serializable)
    SET VeraendertAm = @VeraendertAm
    WHERE mitIDref = @mitIDref AND faeIDref = @faeID
    if @@rowcount = 0
    begin
        INSERT mdb_Faehigkeiten (mitIDref, faeIDref, VeraendertAm)
        VALUES (@mitIDref, @faeID, @VeraendertAm)
    end
commit tran

你必须使用

DECLARE @FaeBezeichnung int = ?
DECLARE @VeraendertAm int = ?
DECLARE @mitIDref int = ?
DECLARE @faeID AS int
begin tran
    SELECT  @faeID = faeID 
    FROM mdb_Faehigkeiten 
    WHERE kurzBez = @FaeBezeichnung 
    UPDATE mdb_Faehigkeiten WITH (serializable)
    SET VeraendertAm = @VeraendertAm
    WHERE 
        mitIDref = @mitIDref AND
         faeIDref = @faeID
    if @@rowcount = 0
    begin
        INSERT mdb_Faehigkeiten (mitIDref, faeIDref, VeraendertAm)
        VALUES (@mitIDref, @faeID, @VeraendertAm)
    end
commit tran

并且你必须小心cmd.Parameters集合/列表中的参数位置。

为什么?因为@VarName特定于SQL Server,但ODBC独立于/不受数据库语言扩展。

补充说明:我会小心TX和错误/异常。例如,我会在BEGIN TRAN之前使用SET XACT_ABORT ON,而在C#中我将截取任何SqlException。另外,我不会使用(serializable)表提示,而是SET TRANSACTION ISOLATION LEVEL SERIALIZABLE之前的BEGIN TRAN... READ COMMITTED之后的COMMIT以及catch之内的SqlException部分1}}。这个主题需要一个单独的问题。

另请注意:对于SQL2005和2008 / [R2](?),为了获取参数列表,我将使用sp_batch_params扩展存储过程:

enter image description here

答案 1 :(得分:0)

将您的SQL脚本调整为这样,并将我使用的数据类型更改为您正在使用的数据类型和值:

DECLARE @FaeBezeichnung int = 1
DECLARE @VeraendertAm int = 2
DECLARE @mitIDref int = 3
DECLARE @faeID AS int
begin tran
    SELECT  @faeID = faeID 
    FROM mdb_Faehigkeiten 
    WHERE kurzBez = @FaeBezeichnung 
    UPDATE mdb_Faehigkeiten WITH (serializable)
    SET VeraendertAm = @VeraendertAm
    WHERE 
        mitIDref = @mitIDref AND
         faeIDref = @faeID
    if @@rowcount = 0
    begin
        INSERT mdb_Faehigkeiten (mitIDref, faeIDref, VeraendertAm)
        VALUES (@mitIDref, @faeID, @VeraendertAm)
    end
commit tran