Ошибка 5407: недопустимая операция для DateTime или Interval внутри хранимой процедуры - PullRequest
0 голосов
/ 03 мая 2018

Я искал этот тип ошибки Ошибка Teradata "5407 Недопустимая операция для DateTime или Interval" здесь и в Интернете, но не смог найти никакого решения.

Проще говоря: в Teradata у меня есть простой sproc, который имеет 2 входа и один выход. Вот что произошло:

Replace PROCEDURE SP.CompUserReturnID (
   IN NTIDVar varchar(50),
   IN CreatedDate TIMESTAMP(6),
   OUT ReturnRes integer
)
BEGIN
    DECLARE res varchar(1000);

    DECLARE RetCompID integer;
    DECLARE ReplaceNTIDVAR varchar(50);

    -- In some cases, the NTIDVar contains the single quote (').  Example:   John'O.Smith@company.com
    -- so we need to replace the single quote
    set ReplaceNTIDVAR = oreplace(NTIDVar,'''','''''');

    set res = 'INSERT INTO tables.Computer (NTID, CreatedDate) VALUES (''' || ReplaceNTIDVAR || ''',' || CreatedDate ||') ';
    EXECUTE IMMEDIATE res;

    -- Do something else
    set ReturnRes = res;

    end;

При выполнении этого простого sproc я получаю сообщение об ошибке:

Ошибка Teradata 5407 Недопустимая операция для DateTime или Interval

Столбец CreatedDate определяется внутри таблицы TD как TimeStamp (6).

Любая подсказка будет оценена.

Спасибо

1 Ответ

0 голосов
/ 03 мая 2018

Ошибка вызвана этой частью, || CreatedDate ||. Для конкатенации требуются строковые операнды, но CreatedDate является меткой времени, и нет автоматических приведений типов для времени и метки времени.

Когда вы добавите явное || CAST(CreatedDate AS VarChar(26)||, вы получите еще одну ошибку, потому что строка, которую вы передаете EXECUTE IMMEDIATE, должна иметь правильный синтаксис, но вы пытаетесь выполнить:

INSERT INTO tables.Computer (NTID, CreatedDate) VALUES ('bla',2018-05-03 12:25:41.65000) 

Таким образом, вам нужно процитировать метку времени (и лучше использовать литерал метки времени):

SET res = 'INSERT INTO Computer (NTID, CreatedDate) VALUES (''' || ReplaceNTIDVAR 
          || ''', TIMESTAMP ''' || Cast( CreatedDate AS VARCHAR(25))  ||''') ';

, что в итоге дает правильный синтаксис:

INSERT INTO Computer (NTID, CreatedDate) VALUES ('bla', TIMESTAMP '2018-05-03 12:27:34.99000') 

НО, нет никаких причин для динамического SQL (который склонен к SQL-инъекции ), просто используйте жестко запрограммированную вставку с параметрами:

INSERT INTO Компьютер (NTID, CreatedDate) ЗНАЧЕНИЯ (: NTIDVar,: CreatedDate);

Конечно, ваш последний SET ReturnRes = res; также потерпит неудачу, потому что ReturnRes - INT.

...