web-dev-qa-db-ja.com

ストアドプロシージャを実行すると、ExecuteNonQuery()は-1を返します。

VisualStudioでストアドプロシージャを実行しようとしています。その下に与えられます。

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 

以下のコードを使用してそうしています。

        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());

しかし、それは私に-1を返します。デバッグで取得したのと同じ値を入力して、このストアドプロシージャを試しました。成功しました。考えられるエラーは何ですか?どうもありがとう!

12
don

_= null_を使用せず、_is null_を使用してください

_IF @existPerson is null
_

_= null_を比較すると、結果は常にfalseになります(_set ansi_nulls off_がない限り、このようなオプションは非推奨であるため、そうすべきではありません)。

さらに良いことに、あなたは使用することができます

_IF NOT EXISTS (SELECT p_ID FROM Student WHERE s_NIC = @nic)
_

また、SCOPE_IDENTITY()の代わりにSET @currentID = (SELECT MAX( p_ID) FROM Person);を使用する必要があります

_SET @currentID = SCOPE_IDENTITY()
_

最後に、戻り値を収集するためのパラメーターも追加する必要があります

_   SqlParameter retValue = cmd.Parameters.Add("return", SqlDbType.Int);
   retValue.Direction = ParameterDirection.ReturnValue;
_

その後

_MessageBox.Show(retValue.Value);
_
15
podiluska

ExecuteNonQueryドキュメントを見てみましょう:

UPDATE、INSERT、およびDELETEステートメントの場合、戻り値はコマンドの影響を受ける行数です。 ...他のすべてのタイプのステートメントの場合、戻り値は-1です。

ストアドプロシージャを呼び出していますが、それ自体は、行数が返される3つのリストされたステートメントのいずれでもありません。


ストアドプロシージャ内のreturnステートメントに渡された値を確認する場合は、コマンドに別のパラメーターを追加し、その Direction を設定する必要があります。プロパティから ReturnValue (このパラメーターに付けた名前は無視されます)

12

この問題を解決するには、「SET NOCOUNT ON」を削除するか、「SETNOCOUNTOFF」に変更します。そして、すべてが正常に動作します!

7
Ahitosh