2016-07-13 2 views
1

는 나는이 저장 프로 시저 작성했습니다 :SCOPE_IDENTITY()가 -1을 반환하는 이유는 무엇입니까?

ALTER PROCEDURE [cairs].[sp_SaveR] 
    -- Add the parameters for the stored procedure here 
@fname nvarchar(50), 
@lname nvarchar(50), 
@mname nchar(10), 
@sigDate date   
AS 
BEGIN 
    SET NOCOUNT ON; 
    insert into tUser 
(fname, 
lname, 
mname, 
sigDate 
) 
values 
(
@fname, 
@lname, 
@mname, 
@sigDate) 

select SCOPE_IDENTITY() 

END 

이 내가 그것을 연결하는 데 사용하는 C# 코드입니다 :

try 
{ 
    using (SqlConnection conn = new SqlConnection(cCon.getConn())) 
    { 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      conn.Open(); 

      cmd.CommandText = "sp_SaveR";           
      cmd.CommandType = CommandType.StoredProcedure; 

      cmd.Parameters.Add(new SqlParameter("@fname", fName)); 
      cmd.Parameters.Add(new SqlParameter("@lname", lName)); 
      cmd.Parameters.Add(new SqlParameter("@mname", mName));      
      cmd.Parameters.Add(new SqlParameter("@sigDate", sigDate)); 

      int userID = (int)cmd.ExecuteNonQuery(); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    throw(ex); 
} 

userID 항상 기록이 성공적으로 삽입 된 경우에도, -1을 반환 DB 테이블에 저장합니다. 왜 이런 일이 생길까요?

+7

'잘못된 방법은 여기에 사용하려는 ExecuteNonQuery' 보인다 - 확실히 당신이 마지막 쿼리의 결과를 소비하고자하고, 그래서'ExecuteReader' (또는 가능성을 ,'ExecuteScalar') 적절한 것으로 보입니다. 또한 현재의 문제와 관련이 없지만 'sp_' 접두사는 사용하지 않아야합니다. 접두사는 시스템 절차를 위해 Microsoft에서 예약합니다. –

+2

이것은 프로 시저에서 리턴 값을 얻고 있기 때문입니다. OUTPUT 변수를 사용해야합니다. 부수적으로 sp_ 접두사를 사용하지 않는 것이 좋습니다. 접두어를 사용하지 않는 것이 좋습니다. http://sqlperformance.com/2012/10/t-sql-queries/sp_prefix –

+0

둘 다 감사합니다! 나는 sp에 대해 전혀 몰랐다. 나는 스토어드 프로 시저에 대한 명명 규칙이라고 생각했다. -/ –

답변

3

ExecuteNonQuery은 결과 집합을 버립니다. 반환되는 숫자는 일반적으로 영향을받는 행의 수이지만 실제로 의존 할 수있는 것은 아닙니다. 귀하의 경우 스토어드 프로 시저를 실행 중이므로 -1을 반환하고 SQL을 인라인하면 1을 반환합니다.

대신 ExecuteScalar을 사용하면 첫 번째 결과 집합의 첫 번째 행에서 첫 번째 열을 읽습니다.

+0

또 다른 옵션은 출력 매개 변수를 프로 시저에 추가하십시오. –

0

이것은 설계대로 작동합니다. 리턴 값은 수정 된 행의 수입니다. 저장 프로 시저를 호출하거나 데이터를 선택하면 값은 -1이됩니다. MSDN에서

은 ...

UPDATE, INSERT를 들어 SqlCommand.ExecuteNonQuery

, DELETE 문, 반환 값은 명령에 의해 영향을받는 행의 수입니다. 테이블에 삽입 또는 업데이트되는 트리거가있는 경우 반환 값에는 삽입 또는 업데이트 작업의 영향을받는 행 수 과 트리거 또는 트리거에 의해 영향을받는 행 수 이 반환됩니다. 다른 모든 유형의 문에 대한 반환 값은 -1입니다. 롤백이 발생하면 값은 -1로 반환됩니다.

0

다음과 같이 ID를 검색하려면 output 매개 변수를 사용해야합니다. C#에서

ALTER PROCEDURE [cairs].[sp_SaveR] 
-- Add the parameters for the stored procedure here 
@fname nvarchar(50), 
@lname nvarchar(50), 
@mname nchar(10), 
@sigDate date, 
@NewId int OUTPUT   
AS 
BEGIN 
SET NOCOUNT ON; 
insert into tUser 
(fname, 
lname, 
mname, 
sigDate 
) 
values 
(
@fname, 
@lname, 
@mname, 
@sigDate) 

select @NewId = SCOPE_IDENTITY() 

END 

:

try 
{ 
    using (SqlConnection conn = new SqlConnection(cCon.getConn())) 
    { 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      conn.Open(); 

      cmd.CommandText = "sp_SaveR";           
      cmd.CommandType = CommandType.StoredProcedure; 

      cmd.Parameters.Add(new SqlParameter("@fname", fName)); 
      cmd.Parameters.Add(new SqlParameter("@lname", lName)); 
      cmd.Parameters.Add(new SqlParameter("@mname", mName));      
      cmd.Parameters.Add(new SqlParameter("@sigDate", sigDate)); 
      cmd.Parameters.Add("@NewId", SqlDbType.Int).Direction = ParameterDirection.Output; 

      cmd.ExecuteNonQuery(); 
      int userId = Convert.ToInt32(cmd.Parameters["@NewId"].Value); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    throw(ex); 
} 
관련 문제