Почему моя хранимая процедура T-SQL не выполняется? - PullRequest
0 голосов
/ 02 июля 2018

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

GLPERIOD

 periodid     char
 strtdate     datetime
 closdate     datetime
 fiscalyr     char

GLPOST

 postdate     datetime
 account      char
 amount       money

Учитывая это, следующая хранимая процедура, параметры которой определены как идентичные типу, который требуется столбцам таблицы, при вызове ничего не возвращает.

PROCEDURE MonthlyActual 
    @P2 CHAR, @P3 CHAR, @P4 CHAR
    SELECT SUM(amount) 
    FROM GLPOST 
    WHERE account = @P2
      AND postdate BETWEEN (SELECT strtdate 
                            FROM GLPERIOD 
                            WHERE periodid = @P3 AND fiscalyr = @P4) AND 
                           (SELECT closedate 
                            FROM GLPERIOD 
                            WHERE periodid = @P3 AND fiscalyr = @P4)
    GROUP BY   
        account

Я пытаюсь назвать это так:

MonthlyActual @P2 = '51080-000', @P3 = 1, @P4 = 2018

MonthlyActual @P2 = '51080-000', @P3 = '1', @P4 = '2018'

... и ничего не получите. Тем не менее, если я жестко закодирую эти значения, код работает отлично. Что я делаю не так?

Я использую SQL Server Management Studio на Windows Server.

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

Я собираюсь догадаться, что ваша хранимая процедура выглядит так:

create stored procedure MonthlyActual (
    @p2 char,
    @p3 char,
    @p4 char
)

Если это так, проблема проста. Объявления для одного символа. Измените их на более разумные типы:

create stored procedure MonthlyActual (
    @account varchar(255),
    @periodid varchar(255),
    @year varchar(255)
)

Я также рекомендую переименовать параметры, чтобы в коде было больше смысла.

Мораль? В SQL Server всегда используйте длины с char() и связанными типами. Длина по умолчанию зависит от контекста и часто приводит к ошибкам, которые трудно отладить.

0 голосов
/ 02 июля 2018

Проблема заключалась в том, что, хотя periodid и fiscalyr относятся к типу данных char, передача им значений char не дала результатов - они не были обрезаны. Хотя periodid и fiscalyr будут содержать только целые числа, тот факт, что база данных была разработана около 20 лет назад, также означал, что в игре были заурядные привычки. В частности, равенство periodid = '1' никогда не выполнялось, потому что оно хранилось как «1».

Установка проверок на WHERE LTRIM( RTRIM( periodid ) ) = LTRIM( RTRIM( @P3 ) ) решает проблему.

0 голосов
/ 02 июля 2018

Сначала переместите две даты для between в отдельные утверждения:

Declare @StartDate as datetime
Declare @EndDate as datetime

Set @StartDate = SELECT strtdate FROM GLPERIOD WHERE periodid = @P3 AND fiscalyr = @P4
Set @EndDate = SELECT closdate FROM GLPERIOD WHERE periodid = @P3 AND fiscalyr = @P4

SELECT 
     SUM(amount) 
FROM 
     GLPOST 
WHERE 
     account = @P2 
     AND postdate BETWEEN @StartDate AND @EndDate 
GROUP BY 
     account

Далее закомментируйте оператор Между и посмотрите, возвращает ли он данные. Если это так, то вы знаете, что проблема с данными даты

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...