복붙노트

[SQL] C #에서 저장 프로 시저에서 반환 값을 얻기

SQL

C #에서 저장 프로 시저에서 반환 값을 얻기

나는 다음과 같은 쿼리를 가지고 :

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE [dbo].[Validate]
@a varchar(50),
@b varchar(50) output

AS

SET @Password = 
(SELECT Password
FROM dbo.tblUser
WHERE Login = @a)

RETURN @b
GO

이것은 완벽하게 정상적으로 컴파일합니다.

C #에서,이 쿼리를 실행하고 반환 값을 얻을합니다.

내 코드는 다음과 같습니다 :

  SqlConnection SqlConn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MyLocalSQLServer"].ConnectionString.ToString());
        System.Data.SqlClient.SqlCommand sqlcomm = new System.Data.SqlClient.SqlCommand("Validate", SqlConn);

        string returnValue = string.Empty;

        try
        {
            SqlConn.Open();
            sqlcomm.CommandType = CommandType.StoredProcedure;

            SqlParameter param = new SqlParameter("@a", SqlDbType.VarChar);
            param.Direction = ParameterDirection.Input;
            param.Value = Username;
            sqlcomm.Parameters.Add(param);



            SqlParameter retval = sqlcomm.Parameters.Add("@b", SqlDbType.VarChar);
            retval.Direction = ParameterDirection.ReturnValue;


            string retunvalue = (string)sqlcomm.Parameters["@b"].Value;

참고 : 코드 단편을 유지하기 위해 컷을 처리하는 예외입니다. 내가 마지막 줄에 도착 매번는, null가 돌려 주어집니다. 이 코드 논리 오류가 무엇입니까?

감사

해결법

  1. ==============================

    1.다드는 좋은 포인트를 만들지 만, 내가 눈치 중요한 것은 쿼리를 실행하지 않을 것입니다 ...

    다드는 좋은 포인트를 만들지 만, 내가 눈치 중요한 것은 쿼리를 실행하지 않을 것입니다 ...

    SqlParameter retval = sqlcomm.Parameters.Add("@b", SqlDbType.VarChar);
    retval.Direction = ParameterDirection.ReturnValue;
    sqlcomm.ExecuteNonQuery(); // MISSING
    string retunvalue = (string)sqlcomm.Parameters["@b"].Value;
    
  2. ==============================

    2.

    retval.Direction = ParameterDirection.Output;
    

    ParameterDirection.ReturnValue 시술하지 출력 파라미터의 "리턴 값"에 사용한다. 그것은 (매개 변수 이름 @RETURN_VALUE 포함) SQL RETURN 문에 의해 반환 된 값을 가져옵니다.

    대신 RETURN 당신은 = 뭔가를 @b 설정해야합니다 @b

    그런데, 반환 값의 매개 변수는 항상 INT,하지 문자열입니다.

  3. ==============================

    3.난 그냥 마지막에 물건을 선택 결국 그래서 나는, 반환 값에 문제의 톤을 가지고 있었다.

    난 그냥 마지막에 물건을 선택 결국 그래서 나는, 반환 값에 문제의 톤을 가지고 있었다.

    이 솔루션은 마지막에 결과를 선택하고 functinon에 쿼리 결과를 반환하기 만했다.

    내 경우에는 나는 수표 존재하고 있었다 :

    IF (EXISTS (SELECT RoleName FROM dbo.Roles WHERE @RoleName = RoleName)) 
        SELECT 1
    ELSE
        SELECT 0
    

    그때

    using (SqlConnection cnn = new SqlConnection(ConnectionString))
    {
        SqlCommand cmd = cnn.CreateCommand();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "RoleExists";
        return (int) cmd.ExecuteScalar()
    }
    

    대신 int 형의 문자열 값과 같은 일을 할 수 있어야합니다.

  4. ==============================

    4.이 요엘의와 메흐 다드의 응답에 구축 : 당신은 결코하는 SqlCommand에 RETVAL의 매개 변수를 바인딩하지 있습니다. 당신은 필요

    이 요엘의와 메흐 다드의 응답에 구축 : 당신은 결코하는 SqlCommand에 RETVAL의 매개 변수를 바인딩하지 있습니다. 당신은 필요

    sqlcomm.Parameters.Add(retval);
    

    당신이 명령을 실행하고 있는지 확인합니다

    sqlcomm.ExecuteNonQuery();
    

    당신이 반환 값 문자열 (ReturnValue를하고 retunvalue)가 왜 확인도하지 않다.

  5. ==============================

    5.당신은 당신의 SQL이 벌금을 컴파일 말하지만, 내가 얻을 : 스칼라 변수 "@Password"를 선언해야합니다.

    당신은 당신의 SQL이 벌금을 컴파일 말하지만, 내가 얻을 : 스칼라 변수 "@Password"를 선언해야합니다.

    또한 당신은 당신의 저장 프로 시저에서 VARCHAR (@b)을 반환하려하지만 SQL Server 저장 프로 시저는 정수를 반환 할 수 있습니다.

    프로 시저를 실행하면 오류를 얻을려고하고있다 :

    X '는 VARCHAR 값을 변환 할 때 변환이 실패'int 데이터 형식입니다. '

  6. ==============================

    6.우리는 select 문 않고 저장 프로 시저에서 값을 반환합니다. 우리는 값을 얻기 위해 "ParameterDirection.ReturnValue"와 "ExecuteScalar는"명령을 사용해야합니다.

    우리는 select 문 않고 저장 프로 시저에서 값을 반환합니다. 우리는 값을 얻기 위해 "ParameterDirection.ReturnValue"와 "ExecuteScalar는"명령을 사용해야합니다.

    CREATE PROCEDURE IsEmailExists
        @Email NVARCHAR(20)
    AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;
    
        -- Insert statements for procedure here
        IF EXISTS(SELECT Email FROM Users where Email = @Email)
        BEGIN
            RETURN 0 
        END
        ELSE
        BEGIN
            RETURN 1
        END
    END
    

    C #에서

    GetOutputParaByCommand("IsEmailExists")
    
    public int GetOutputParaByCommand(string Command)
            {
                object identity = 0;
                try
                {
                    mobj_SqlCommand.CommandText = Command;
                    SqlParameter SQP = new SqlParameter("returnVal", SqlDbType.Int);
                    SQP.Direction = ParameterDirection.ReturnValue;
                    mobj_SqlCommand.Parameters.Add(SQP);
                    mobj_SqlCommand.Connection = mobj_SqlConnection;
                    mobj_SqlCommand.ExecuteScalar();
                    identity = Convert.ToInt32(SQP.Value);
                    CloseConnection();
                }
                catch (Exception ex)
                {
    
                    CloseConnection();
                }
                return Convert.ToInt32(identity);
            }
    

    우리는 C #을 기능 이상 사용하여 SP "IsEmailExists"의 반환 값을 얻을.

  7. ==============================

    7.이 SP는 아주 이상한 보인다. 그것은 @b에 전달되는 수정하지 않습니다. 그리고데도 SP에서 당신은 할당 아무것도 @b 없습니다. 이 SP가 전혀 작동하지 않도록 그리고 @Password은 정의되어 있지 않습니다.

    이 SP는 아주 이상한 보인다. 그것은 @b에 전달되는 수정하지 않습니다. 그리고데도 SP에서 당신은 할당 아무것도 @b 없습니다. 이 SP가 전혀 작동하지 않도록 그리고 @Password은 정의되어 있지 않습니다.

    나는 당신이 실제로 @Password을 반환하거나 SET의 @b를 할 거라 생각 = (SELECT ...)

    당신은 (주, 아니 OUTPUT 매개 변수)에 SP를 수정하면 훨씬 간단 할 것이다 :

    set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go
    
    ALTER PROCEDURE [dbo].[Validate] @a varchar(50)
    
    AS
    
    SELECT TOP 1 Password FROM dbo.tblUser WHERE Login = @a
    

    그런 다음 코드는 cmd.ExecuteScalar를 사용하고, 그 결과를받을 수 있습니다.

  8. ==============================

    8.이 의지에 도움이 될 수 있습니다.

    이 의지에 도움이 될 수 있습니다.

    데이터베이스 스크립트

    USE [edata]
    GO
    
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    
    CREATE PROCEDURE [dbo].[InsertNewUser](
     @neuname NVARCHAR(255),
     @neupassword NVARCHAR(255),
     @neuposition NVARCHAR(255)
     )
    
    AS
    
    BEGIN 
    
    BEGIN TRY
    
     DECLARE @check INT;
    
     SET @check = (SELECT count(eid) FROM eusers WHERE euname = @neuname);
    
    IF(@check = 0)
    
    INSERT INTO  eusers(euname,eupassword,eposition)
    VALUES(@neuname,@neupassword,@neuposition);
    
    DECLARE @lastid INT;
    
    SET @lastid = @@IDENTITY;
    
    RETURN @lastid;
    
    
    END TRY
    
    
    BEGIN CATCH
    
    SELECT ERROR_LINE() as errline,
           ERROR_MESSAGE() as errmessage,
           ERROR_SEVERITY() as errsevirity
    
    END CATCH
    
    END
    

    응용 프로그램 구성 파일 :

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <appSettings>
        <add key="conStr" value="Data Source=User\SQLEXPRESS;Initial Catalog=edata;Integrated Security=True"/>
      </appSettings>
    </configuration>
    

    데이터 액세스 계층 (DAL) :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Configuration;
    using System.Data;
    using System.Data.SqlClient;
    namespace DAL
    {
        public static class DAL
        {
            public static SqlConnection conn;
    
            static DAL()
            {
    
    
                conn = new SqlConnection(ConfigurationManager.AppSettings["conStr"].ToString());
                conn.Open();
    
    
            }
    
    
        }
    }
    

    비즈니스 로직 레이어 (BLL) :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Data;
    using System.Data.SqlClient;
    using DAL;
    namespace BLL
    {
        public static class BLL
        {
    
    
            public static int InsertUser(string lastid, params SqlParameter[] coll)
            {
    
                int lastInserted = 0;
    
                try
                {
    
    
                    SqlCommand comm = new SqlCommand();
    
                    comm.Connection = DAL.DAL.conn;
    
    
                    foreach (var param in coll)
                    {
    
                        comm.Parameters.Add(param);
    
                    }
    
                    SqlParameter lastID = new SqlParameter();
                    lastID.ParameterName = lastid;
                    lastID.SqlDbType = SqlDbType.Int;
                    lastID.Direction = ParameterDirection.ReturnValue;
    
                    comm.Parameters.Add(lastID);
    
                    comm.CommandType = CommandType.StoredProcedure;
    
                    comm.CommandText = "InsertNewUser";
    
                    comm.ExecuteNonQuery();
    
                    lastInserted = (int)comm.Parameters[lastid].Value;
    
                }
    
                catch (SqlException ex)
                {
    
    
                }
    
                finally {
    
                    if (DAL.DAL.conn.State != ConnectionState.Closed) {
    
                        DAL.DAL.conn.Close();
                    }
    
                }           
    
                return lastInserted;
    
            }
    
        }
    }
    

    구현 :

    BLL.BLL.InsertUser("@lastid",new SqlParameter("neuname","Ded"),
                     new SqlParameter("neupassword","Moro$ilka"),
                     new SqlParameter("neuposition","Moroz")
                     );
    
  9. ==============================

    9.여러 문제가 여기에 있습니다 :

    여러 문제가 여기에 있습니다 :

    여기서 출력 매개 변수를 이용한 용액이다. 이것은 테스트되었습니다 :

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROCEDURE [dbo].[Validate]
        @a varchar(50),
        @b varchar(50) OUTPUT
    AS
    BEGIN
        DECLARE @b AS varchar(50) = (SELECT Password FROM dbo.tblUser WHERE Login = @a)
        SELECT @b;
    END
    
    SqlConnection SqlConn = ...
    var sqlcomm = new SqlCommand("Validate", SqlConn);
    
    string returnValue = string.Empty;
    
    try
    {
        SqlConn.Open();
        sqlcomm.CommandType = CommandType.StoredProcedure;
    
        SqlParameter param = new SqlParameter("@a", SqlDbType.VarChar);
        param.Direction = ParameterDirection.Input;
        param.Value = Username;
        sqlcomm.Parameters.Add(param);
    
        SqlParameter output = sqlcomm.Parameters.Add("@b", SqlDbType.VarChar);
        ouput.Direction = ParameterDirection.Output;
    
        sqlcomm.ExecuteNonQuery(); // This line was missing
    
        returnValue = output.Value.ToString();
    
        // ... the rest of code
    
    } catch (SqlException ex) {
        throw ex;
    }
    
  10. ==============================

    10.당신은 반환 값과 출력 변수의 개념을 혼합했다. 1 출력 변수 :

    당신은 반환 값과 출력 변수의 개념을 혼합했다. 1 출력 변수 :

    Database----->:
    create proc MySP
    @a varchar(50),
    @b varchar(50) output
    AS
    SET @Password = 
    (SELECT Password
    FROM dbo.tblUser
    WHERE Login = @a)
    
    C# ----->:
    
    SqlConn.Open();
    sqlcomm.CommandType = CommandType.StoredProcedure;
    
    SqlParameter param = new SqlParameter("@a", SqlDbType.VarChar);
    param.Direction = ParameterDirection.Input;//This is optional because Input is the default
    
    param.Value = Username;
    sqlcomm.Parameters.Add(param);
    
    SqlParameter outputval = sqlcomm.Parameters.Add("@b", SqlDbType.VarChar);
    outputval .Direction = ParameterDirection.Output//NOT ReturnValue;
    
    
    string outputvalue = sqlcomm.Parameters["@b"].Value.ToString();
    
  11. ==============================

    11.이것에 대해 해결하는 방법은 두 가지가 있습니다. 첫 번째 (반환하지 않음)를 출력 변수의 값을 저장하는 저장 프로 시저를 설정.

    이것에 대해 해결하는 방법은 두 가지가 있습니다. 첫 번째 (반환하지 않음)를 출력 변수의 값을 저장하는 저장 프로 시저를 설정.

    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go
    
    ALTER PROCEDURE [dbo].[Validate]
    @a varchar(50),
    @b varchar(50) output
    
    AS
    
    SET @b = 
    (SELECT Password
    FROM dbo.tblUser
    WHERE Login = @a)
    
    RETURN
    GO
    

    이것은 것입니다하지만 @b에 암호 당신은 반환 매개 변수로 얻을 것이다. 그런 다음 C #을 이렇게 그것을 얻을 수 있습니다 :

    SqlConnection SqlConn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MyLocalSQLServer"].ConnectionString.ToString());
        System.Data.SqlClient.SqlCommand sqlcomm = new System.Data.SqlClient.SqlCommand("Validate", SqlConn);
    
        string returnValue = string.Empty;
    
        try
        {
            SqlConn.Open();
            sqlcomm.CommandType = CommandType.StoredProcedure;
    
            SqlParameter param = new SqlParameter("@a", SqlDbType.VarChar, 50);
            param.Direction = ParameterDirection.Input;
            param.Value = Username;
            sqlcomm.Parameters.Add(param);
    
    
    
            SqlParameter retval = new SqlParameter("@b", SqlDbType.VarChar, 50);
            retval.Direction = ParameterDirection.ReturnValue;
            sqlcomm.Parameters.Add(retval);
    
            sqlcomm.ExecuteNonQuery();
            SqlConn.Close();
    
            string retunvalue = retval.Value.ToString();
         }
    
  12. ==============================

    12.때 사용

    때 사용

    cmd.Parameters.Add("@RETURN_VALUE", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;
    

    그런 다음 저장 프로 시저가 확인해야합니다

    return @RETURN_VALUE;
    

    저장 프로 시저의 끝.

  13. ==============================

    13.당신이 저장 프로 시저에 사용자 이름과 암호를 통과 로그인이 성공 여부를 알 수 여부와 오류가 저장 프로 시저에서 발생했는지 확인해야 가정하자.

    당신이 저장 프로 시저에 사용자 이름과 암호를 통과 로그인이 성공 여부를 알 수 여부와 오류가 저장 프로 시저에서 발생했는지 확인해야 가정하자.

    public bool IsLoginSuccess(string userName, string password)
    {
        try
        {
            SqlConnection SQLCon = new SqlConnection(WebConfigurationManager.ConnectionStrings["SqlConnector"].ConnectionString);
            SqlCommand sqlcomm = new SqlCommand();
            SQLCon.Open();
            sqlcomm.CommandType = CommandType.StoredProcedure;
            sqlcomm.CommandText = "spLoginCheck"; // Stored Procedure name
            sqlcomm.Parameters.AddWithValue("@Username", userName); // Input parameters
            sqlcomm.Parameters.AddWithValue("@Password", password); // Input parameters
    
            // Your output parameter in Stored Procedure           
            var returnParam1 = new SqlParameter
            {
                ParameterName = "@LoginStatus",
                Direction = ParameterDirection.Output,
                Size = 1                    
            };
            sqlcomm.Parameters.Add(returnParam1);
    
            // Your output parameter in Stored Procedure  
            var returnParam2 = new SqlParameter
            {
                ParameterName = "@Error",
                Direction = ParameterDirection.Output,
                Size = 1000                    
            };
    
            sqlcomm.Parameters.Add(returnParam2);
    
            sqlcomm.ExecuteNonQuery(); 
            string error = (string)sqlcomm.Parameters["@Error"].Value;
            string retunvalue = (string)sqlcomm.Parameters["@LoginStatus"].Value;                    
        }
        catch (Exception ex)
        {
    
        }
        return false;
    }
    

    있는 Web.Config에 연결 문자열

    <connectionStrings>
        <add name="SqlConnector"
             connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=Databasename;User id=yourusername;Password=yourpassword"
             providerName="System.Data.SqlClient" />
      </connectionStrings>
    

    그리고 여기에 저장 프로 시저는 참조 용입니다

    CREATE PROCEDURE spLoginCheck
        @Username Varchar(100),
        @Password Varchar(100) ,
        @LoginStatus char(1) = null output,
        @Error Varchar(1000) output 
    AS
    BEGIN
    
        SET NOCOUNT ON;
        BEGIN TRY
            BEGIN
    
                SET @Error = 'None'
                SET @LoginStatus = ''
    
                IF EXISTS(SELECT TOP 1 * FROM EMP_MASTER WHERE EMPNAME=@Username AND EMPPASSWORD=@Password)
                BEGIN
                    SET @LoginStatus='Y'
                END
    
                ELSE
                BEGIN
                    SET @LoginStatus='N'
                END
    
            END
        END TRY
    
        BEGIN CATCH
            BEGIN           
                SET @Error = ERROR_MESSAGE()
            END
        END CATCH
    END
    GO
    
  14. ==============================

    14.코드 반환이 라인은 SQL 서버에서 프로 시저 반환 값을 저장 저장

    코드 반환이 라인은 SQL 서버에서 프로 시저 반환 값을 저장 저장

    cmd.Parameters.Add("@id", System.Data.SqlDbType.Int).Direction = System.Data.ParameterDirection.ReturnValue;                
    cmd.ExecuteNonQuery();
    

    쿼리 값의 실행은 SP에서 반환합니다 후

    id = (int)cmd.Parameters["@id"].Value;
    
  15. from https://stackoverflow.com/questions/706361/getting-return-value-from-stored-procedure-in-c-sharp by cc-by-sa and MIT license