복붙노트

[SQL] 프로 시저 또는 함수! 지정된 인수를 너무 많이

SQL

프로 시저 또는 함수! 지정된 인수를 너무 많이

나는 SQL Server 2008 R2의 내 첫 번째 저장 프로 시저를 개발하고하고 필요로하는 조언은 오류 메시지에 관한.

내가 저장 프로 시저를 실행 한 후 얻을 수있는 [DBO]. [M_UPDATES] etl_M_Update_Promo라는 또 다른 저장 프로 시저를 호출하는.

호출 할 때 [dbo가] [M_UPDATES (코드는 아래 참조)를 통해 쿼리 창에 표시되어있는 것을 쿼리 '저장 프로 시저를 실행'마우스 오른쪽 버튼으로 클릭하고. :

USE [Database_Test]
GO

DECLARE @return_value int

EXEC    @return_value = [dbo].[M_UPDATES]

SELECT  'Return Value' = @return_value

GO

출력은

질문 :이 오류 메시지가 정확히 무엇을 의미 하는가, 즉 너무 많은 인수 어디에? 어떻게 그들을 식별?

이 오류 메시지에 대해 물어 여러 스레드를 찾았지만, 제공되는 코드 (어쨌든이 아니라면 C 번호와 같은 다른 언어로) 모든 광산 달랐다. 답변 아무도 내 SQL 쿼리 (즉, SP에)의 문제를 해결하지 그래서.

참고 : 나는 두 개의 SP를 위해 사용되는 코드를 제공하지만, 나는 데이터베이스 이름, 테이블 이름과 열 이름을 변경 아래. 그래서, 명명 규칙에 대해 걱정하지주십시오, 이들은 단지 예를 들어 이름은!

어떤 조언과 생각에 미리 감사드립니다!

SP1 (1) 코드 [DBO]. M_UPDATES]

USE [Database_Test]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[ M_UPDATES] AS
declare @GenID bigint
declare @Description nvarchar(50)

Set @GenID = SCOPE_IDENTITY()
Set @Description = 'M Update'

BEGIN
EXEC etl.etl_M_Update_Promo @GenID, @Description
END

GO

(2) SP2에 대한 코드 [etl_M_Update_Promo]

USE [Database_Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [etl].[etl_M_Update_Promo]
@GenId bigint = 0
as

declare @start datetime = getdate ()
declare @Process varchar (100) = 'Update_Promo'
declare @SummeryOfTable TABLE (Change varchar (20))
declare @Description nvarchar(50)
declare @ErrorNo int
, @ErrorMsg varchar (max)
declare @Inserts int = 0
, @Updates int = 0
, @Deleted int = 0
, @OwnGenId bit = 0

begin try


if @GenId = 0 begin
INSERT INTO Logging.dbo.ETL_Gen (Starttime)
VALUES (@start)

SET @GenId = SCOPE_IDENTITY()
SET @OwnGenId = 1
end


MERGE [Database_Test].[dbo].[Promo] AS TARGET
USING OPENQUERY( M ,'select * from m.PROMO' ) AS SOURCE 
ON (TARGET.[E] = SOURCE.[E]) 


WHEN MATCHED AND  TARGET.[A] <> SOURCE.[A]
  OR TARGET.[B] <> SOURCE.[B]
  OR TARGET.[C] <> SOURCE.[C]
  THEN 
UPDATE SET TARGET.[A] = SOURCE.[A]
  ,TARGET.[B] = SOURCE.[B]
  , TARGET.[C] = SOURCE.[c]

WHEN NOT MATCHED BY TARGET THEN 
INSERT ([E]
  ,[A]
  ,[B]
  ,[C]
  ,[D]
  ,[F]
  ,[G]
  ,[H]
  ,[I]
  ,[J]
  ,[K]
  ,[L]  
  ) 
VALUES (SOURCE.[E]
  ,SOURCE.[A]
  ,SOURCE.[B]
  ,SOURCE.[C]
  ,SOURCE.[D]
  ,SOURCE.[F]
  ,SOURCE.[G]
  ,SOURCE.[H]
  ,SOURCE.[I]
  ,SOURCE.[J]
  ,SOURCE.[K]
  ,SOURCE.[L]
)

OUTPUT $ACTION  INTO @SummeryOfTable; 


with cte as (
SELECT
Change,
COUNT(*) AS CountPerChange
FROM @SummeryOfTable
GROUP BY Change
)

SELECT
@Inserts =
    CASE Change
        WHEN 'INSERT' THEN CountPerChange ELSE @Inserts
    END,
@Updates =
    CASE Change
        WHEN 'UPDATE' THEN CountPerChange ELSE @Updates
    END,
@Deleted =
    CASE Change
        WHEN 'DELETE' THEN CountPerChange ELSE @Deleted
    END
FROM cte


INSERT INTO Logging.dbo.ETL_log (GenID, Startdate, Enddate, Process, Message, Inserts, Updates, Deleted,Description)
VALUES (@GenId, @start, GETDATE(), @Process, 'ETL succeded', @Inserts, @Updates,     @Deleted,@Description)


if @OwnGenId = 1
UPDATE Logging.dbo.ETL_Gen
SET Endtime = GETDATE()
WHERE ID = @GenId

end try
begin catch

SET @ErrorNo = ERROR_NUMBER()
SET @ErrorMsg = ERROR_MESSAGE()

INSERT INTO Logging.dbo.ETL_Log (GenId, Startdate, Enddate, Process, Message, ErrorNo, Description)
VALUES (@GenId, @start, GETDATE(), @Process, @ErrorMsg, @ErrorNo,@Description)


end catch
GO

해결법

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

    1.당신은이 개 매개 변수 (@GenId 및 @description)로 함수를 호출 :

    당신은이 개 매개 변수 (@GenId 및 @description)로 함수를 호출 :

    EXEC etl.etl_M_Update_Promo @GenID, @Description
    

    이 기능을 선언 한 그러나 1 개 인수를합니다 :

    ALTER PROCEDURE [etl].[etl_M_Update_Promo]
        @GenId bigint = 0
    

    SQL 서버는 [etl_M_Update_Promo]가 단 1 개 매개 변수 (@GenId) 소요 있음을 말하고있다

    당신은 @description를 지정하여 두 개의 매개 변수를 사용하는 절차를 변경할 수 있습니다.

    ALTER PROCEDURE [etl].[etl_M_Update_Promo]
        @GenId bigint = 0,
        @Description NVARCHAR(50)
    AS 
    
    .... Rest of your code.
    
  2. ==============================

    2.이 답변은 제목이 아닌 원래의 게시물의 특정 사례를 기반으로합니다.

    이 답변은 제목이 아닌 원래의 게시물의 특정 사례를 기반으로합니다.

    나는이 짜증나는 오류를 던지는 유지 삽입 절차가 있고, 오류가 말한다하더라도, "절차는 .... 너무 많은 인수가 지정이"사실은 절차가 충분한 인수를하지가 않은 것입니다.

    테이블은 증분 id 컬럼을했고,이 증가하기 때문에, 나는 시저에 변수 / 인수로 추가 귀찮게하지 않았지만, 그들이처럼 내가 @Id로 추가, 그래서 그것이 필요하다고 밝혀졌다과 비올라 말 ... 그것은 작동합니다.

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

    3.를 정의하기 전에 다음 명령을 사용하여

    를 정의하기 전에 다음 명령을 사용하여

    cmd.Parameters.Clear()
    
  4. ==============================

    4.나와 같은 문제가있을 수 있습니다 사람들을 위해, 나는 DB 내가 DB 내가 사용되어 있어야 마스터 실제로이었다 사용하고되지 않았습니다이 오류가 발생했습니다.

    나와 같은 문제가있을 수 있습니다 사람들을 위해, 나는 DB 내가 DB 내가 사용되어 있어야 마스터 실제로이었다 사용하고되지 않았습니다이 오류가 발생했습니다.

    수동으로 그냥 넣어 스크립트의 상단에 사용 [DBNAME], 또는는 SQL Server Management Studio의 GUI에서 사용중인 DB를 변경합니다.

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

    5.지금까지 제공되는 모든 답변에 덧붙여, 당신이 ADO.Net을 사용하여 데이터베이스 목록에서 데이터를 저장할 때 일어날 수있는이 예외를 발생하는 또 다른 이유.

    지금까지 제공되는 모든 답변에 덧붙여, 당신이 ADO.Net을 사용하여 데이터베이스 목록에서 데이터를 저장할 때 일어날 수있는이 예외를 발생하는 또 다른 이유.

    많은 개발자들이 실수로 루프 또는 foreach 문에 사용할 당신이 예를 들어,이 코드 샘플처럼 가지고 있는지 확인을 피하기 위해 루프 외부에서 실행하도록하는 SqlCommand를 떠날 것이다 :

    public static void Save(List<myClass> listMyClass)
        {
            using (var Scope = new System.Transactions.TransactionScope())
            {
                if (listMyClass.Count > 0)
                {
                    for (int i = 0; i < listMyClass.Count; i++)
                    {
                        SqlCommand cmd = new SqlCommand("dbo.SP_SaveChanges", myConnection);
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.Clear();
    
                        cmd.Parameters.AddWithValue("@ID", listMyClass[i].ID);
                        cmd.Parameters.AddWithValue("@FirstName", listMyClass[i].FirstName);
                        cmd.Parameters.AddWithValue("@LastName", listMyClass[i].LastName);
    
                        try
                        {
                            myConnection.Open();
                            cmd.ExecuteNonQuery();
                        }
                        catch (SqlException sqe)
                        {
                            throw new Exception(sqe.Message);
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(ex.Message);
                        }
                        finally
                        {
                            myConnection.Close();
                        }
                    }
                }
                else
                {
                    throw new Exception("List is empty");
                }
    
                Scope.Complete();
            }
        }
    
  6. from https://stackoverflow.com/questions/17292705/procedure-or-function-has-too-many-arguments-specified by cc-by-sa and MIT license