2013-10-24 4 views
2

Это, кажется, довольно распространенная проблема, и я почесываю голову о том, почему это происходит. Я работаю с программным приложением, в котором у меня нет прямого доступа к исходному коду (я могу просматривать его только с помощью .NET Reflector).Проблема с хранимой процедурой: «Слишком много аргументов»

Хранимая процедура выглядит следующим образом:

ALTER PROCEDURE [dbo].[CS_GetMessages] (
    @CustomerID C_ID, @Level C_Integer, @UsersTimeZoneOffset C_Integer 
    ) 
AS 
BEGIN 
    SET NOCOUNT ON 
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

    DECLARE @Date Datetime 
    SELECT @Date = CONVERT(nvarchar(10), getutcdate(), 101) 

    SELECT 
     [MessageID] 

    FROM 
     [dbo].[Messages] 
    WHERE 
     ([CustomerID] = @CustomerID OR [CustomerID] IS NULL) 
     AND Enabled = 1 
     AND Deleted = 0 
     AND (EffectiveDate IS NULL OR @Date >= CONVERT(nvarchar(10), DATEADD(minute, @UsersTimeZoneOffset, EffectiveDate), 101)) 
     AND (ExpiryDate IS NULL OR @Date < CONVERT(nvarchar(10), DATEADD(minute, @UsersTimeZoneOffset, ExpiryDate), 101)) 
     AND Publish = 1 
     AND Level = ISNULL(@Level, Level) 
    ORDER BY MaintenanceDate DESC 

END 

Теперь, в соответствии с исходным кодом (к сожалению, из-за лицензирования, я не могу вставить его), он посылает соответствующее количество параметров. SQL Profiler показывает, что это правильно тоже:

exec CS_GetMessages @CustomerID=N'CT000001',@Level=NULL,@UsersTimezoneOffset=0 

Однако кидает ошибку:

Error: 8144, Severity: 16, State: 2 Procedure or function CS_GetMessages has too many arguments specified. 

Но, если я запустить процедуру вручную, она возвращает значение правильно. Я использовал следующий код теста:

DECLARE @return_value int 

EXEC @return_value = [dbo].[CS_GetMessages] 
     @CustomerID = 'CT000001', 
     @Level = NULL, 
     @UsersTimeZoneOffset = 0 

SELECT 'Return Value' = @return_value 

GO 

Обратите внимание, что нет никаких данных, поскольку база данных является пустым (пустая таблица), поэтому соответствующим образом возвращает 0. Любые идеи о том, что могло случиться?

UPDATE: Исходный код, который делает базы данных вызова:.

private SystemMessageManager LoadSystemMessages() 
     { 
      int paramValue = Conversions.ToInteger(Utility.DataFromSession("UsersTimezoneOffset", string.Empty)); 
      SystemMessageManager messageManager = new SystemMessageManager(); 
      CriteriaCollection loadCriteria = new CriteriaCollection(); 
      CriteriaCollection criterias2 = loadCriteria; 
      criterias2.Add("CustomerID", DbType.String, Utility.GetCurrentCustomer().CustomerID, ParameterDirection.Input, ""); 
      criterias2.Add("Level", DbType.Int32, null, ParameterDirection.Input, ""); 
      criterias2.Add("UsersTimezoneOffset", DbType.Int32, paramValue, ParameterDirection.Input, ""); 
      criterias2 = null; 
      messageManager.Load(loadCriteria); 
      this.CheckForDeactivation(messageManager); 
      return messageManager; 
     } 
+0

Вы указываете больше параметров в коде? – Szymon

+0

@Szymon Нет, код показывает соответствующее количество аргументов (3). –

+1

Возможно ли, что у вас есть два объекта с одинаковым именем и разными владельцами? Потому что в вашем рабочем примере у вас есть [[dbo]. [CS_GetMessages] », и в вашем коде, который вы получаете ошибку, у вас есть только« CS_GetMessages », так что, если вы укажете владельца? –

ответ

1

ALTER PROCEDURE [DBO] [CS_GetMessages] ( @CustomerID C_ID, @Level C_Integer, @UsersTimeZoneOffset C_Integer )

Изменить ваш код до

ALTER PROCEDURE [dbo].[CS_GetMessages] (
    @CustomerID BigInt, @Level Integer=NULL, @UsersTimeZoneOffset Integer 
    ) 

По умолчанию целое число равно 0 не равно нулю. Поэтому вам нужно сделать это как null.

exec CS_GetMessages @CustomerID=1,@Level=NULL,@UsersTimezoneOffset=0 
Смежные вопросы