执行存储过程时,ExecuteNonQuery()返回-1

don*_*don 12 c# sql sql-server stored-procedures visual-studio-2010

我正在尝试在Visual Studio中执行存储过程.它给出如下.

CREATE PROCEDURE [dbo].[addStudent] 
    @stuName varchar(50), 
    @address varchar(100),
    @tel varchar(15),
    @etel varchar(15),
    @nic varchar (10),
    @dob date


AS 
BEGIN   
    SET NOCOUNT ON;

    DECLARE @currentID INT
    DECLARE @existPerson INT
    SET @existPerson = (SELECT p_ID FROM Student WHERE s_NIC = @nic);
    IF @existPerson = null
        BEGIN
            INSERT INTO Person (p_Name, p_RegDate, p_Address, p_Tel, p_EmergeNo, p_Valid, p_Userlevel)
            VALUES (@stuName,  GETDATE(), @address, @tel, @etel, 0, 'Student' );
            SET @currentID = (SELECT MAX( p_ID) FROM Person); 
            INSERT INTO Student (p_ID, s_Barcode, s_DOB, s_NIC) VALUES (@currentID , NULL, @dob, @nic);
            return 0;
        END
    ELSE
        return -1;
END 
Run Code Online (Sandbox Code Playgroud)

我这样做是通过使用下面的代码.

        SqlConnection con = new SqlConnection();
        Connect conn = new Connect();
        con = conn.getConnected();
        con.Open();
        cmd = new SqlCommand("addStudent", con);
        cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add("@stuName", SqlDbType.VarChar).Value = nameTxt.Text.ToString();
                cmd.Parameters.Add("@address", SqlDbType.VarChar).Value = addressTxt.Text.ToString();
                cmd.Parameters.Add("@tel", SqlDbType.VarChar).Value = telTxt.Text.ToString();
                cmd.Parameters.Add("@etel", SqlDbType.VarChar).Value = emerTxt.Text.ToString();
                cmd.Parameters.Add("@nic", SqlDbType.VarChar).Value = nicTxt.Text.ToString();
                cmd.Parameters.Add("@dob", SqlDbType.DateTime).Value = dobTime.Value.ToString("MM-dd-yyyy");

                    int n = cmd.ExecuteNonQuery();
                    MessageBox.Show(n.ToString());
Run Code Online (Sandbox Code Playgroud)

但它让我回归-1.我通过输入从调试中捕获的相同值来尝试此存储过程.它很成功.什么可能是错误?非常感谢!

pod*_*ska 16

不要使用= null,使用is null

IF @existPerson is null
Run Code Online (Sandbox Code Playgroud)

当你比较任何东西时= null,结果总是假的(除非你有set ansi_nulls off,你不应该,因为这样的选项已被弃用)

更好的是,你可以使用

IF NOT EXISTS (SELECT p_ID FROM Student WHERE s_NIC = @nic)
Run Code Online (Sandbox Code Playgroud)

此外,你应该使用SCOPE_IDENTITY()而不是SET @currentID = (SELECT MAX( p_ID) FROM Person);

SET @currentID = SCOPE_IDENTITY()
Run Code Online (Sandbox Code Playgroud)

最后,您还需要添加一个参数来收集返回值

   SqlParameter retValue = cmd.Parameters.Add("return", SqlDbType.Int);
   retValue.Direction = ParameterDirection.ReturnValue;
Run Code Online (Sandbox Code Playgroud)

然后

MessageBox.Show(retValue.Value);
Run Code Online (Sandbox Code Playgroud)


Dam*_*ver 12

让我们来看看文档ExecuteNonQuery:

对于UPDATE,INSERT和DELETE语句,返回值是受命令影响的行数.... 对于所有其他类型的语句,返回值为-1.

您正在调用存储过程,该存储过程本身不是返回行计数的3个列出的语句.


如果要确定传递给return存储过程中的语句的值,则需要向该命令添加另一个参数,并将其Direction属性设置为ReturnValue(将忽略您为此参数指定的名称)

  • 这是错误的,如果存储过程正在执行更新,插入或删除它将返回受此命令影响的行数(如果ExecuteNonQuery调用它).在这种情况下,存储过程不被视为语句,存储过程内的语句是. (3认同)

小智 7

要解决此问题,只需删除"SET NOCOUNT ON"或将其更改为"SET NOCOUNT OFF".一切正常!