Ошибка конвертации INTEGER в CHARACTER

Модераторы: kdv, CyberMax

Ответить
Igor321
Сообщения: 3
Зарегистрирован: 16 мар 2010, 11:22

Ошибка конвертации INTEGER в CHARACTER

Сообщение Igor321 » 16 мар 2010, 11:40

Доброе время суток !

FireBird 2.1.

Есть такая таблица

Код: Выделить всё

CREATE TABLE CLIENTS (
    CLIENTID  CHAR(10) NOT NULL,
    BORNDATE  DATE,
    TEXTCODE  CHAR(4),
    SEX       INTEGER,
    REGIONID  INTEGER NOT NULL
)
И такой триггер на вставку записи:

Код: Выделить всё

CREATE OR ALTER TRIGGER CLIENTS_BI0 FOR CLIENTS
ACTIVE BEFORE INSERT POSITION 0
AS
  DECLARE VARIABLE Fday    SMALLINT;
  DECLARE VARIABLE FTxtDay   CHAR(2);
  DECLARE VARIABLE FTxtMonth CHAR(2);
  DECLARE VARIABLE FMonth  SMALLINT;

  DECLARE VARIABLE FPrefix CHAR(3);
BEGIN
  IF (NEW.CLIENTID IS NULL)
  THEN BEGIN

    IF ((NOT(NEW.BORNDATE IS NULL))AND(NOT(NEW.TEXTCODE IS NULL)))
    THEN BEGIN
      FDay = EXTRACT(DAY FROM NEW.BORNDATE);
      FMonth = EXTRACT(MONTH FROM NEW.BORNDATE);
      IF (fday < 10)
      THEN FTxtDay = '0' || CAST(Fday AS CHARACTER);
      ELSE FTxtDay = CAST(Fday AS CHARACTER);
      IF (FMonth < 10)
      THEN FTxtMonth = '0' || CAST(FMonth AS CHARACTER);
      ELSE FTxtMonth = CAST(FMonth AS CHARACTER);
      NEW.CLIENTID = UPPER(NEW.TEXTCODE) || FTxtDay || FTxtMonth || SUBSTRING(EXTRACT(YEAR FROM NEW.BORNDATE) FROM 3);
    END
    ELSE BEGIN
      IF ((NEW.REGIONID IS NULL)OR(NEW.REGIONID = 0))
      THEN FPrefix = '';
      ELSE BEGIN
        IF (NEW.REGIONID < 10)
        THEN FPrefix = '00';
        ELSE IF (NEW.REGIONID < 100)
             THEN FPrefix = '0';
             ELSE FPrefix = '';
      END
      NEW.CLIENTID = FPrefix || (CAST(NEW.REGIONID AS CHARACTER))|| CAST(GEN_ID(gen_clientid, 1) AS CHARACTER);
    END
  END
  NEW.TEXTCODE = UPPER(NEW.TEXTCODE);
END
Смысл триггера в том что:
1. для клиента указывается специальный текстовый код (четыре символа) + дата рождения и из них делается уникальный идентификатор (придумал не я...);
2. Если нет текстового кода или нет даты рождения, тогда уникальный идентификатор формируется следующим образом: Поле REGIONID в текстовом представлении + Значение генератора gen_clientid.

Триггер добавляется, но при попытке добавить запись с нулевыми текстовым кодом и датой рождения, но с ненулевым REGIONID БД выводит ошибку (REGIONID = 15 в данном случае):

Код: Выделить всё

Overflow occurred during data type conversion.
conversion error from string "15".
At trigger 'CLIENTS_BI0' line: 36, col: 7.
Не судите строго, я пользуюсь CAST первый раз... может быть что то я не доглядел ?

Igor321
Сообщения: 3
Зарегистрирован: 16 мар 2010, 11:22

Re: Ошибка конвертации INTEGER в CHARACTER

Сообщение Igor321 » 16 мар 2010, 12:21

Теперь заработало, но я не понимаю почему...
Текст триггера:

Код: Выделить всё

CREATE OR ALTER TRIGGER CLIENTS_BI0 FOR CLIENTS
ACTIVE BEFORE INSERT POSITION 0
AS
  DECLARE VARIABLE Fday    SMALLINT;
  DECLARE VARIABLE FTxtDay   CHAR(2);
  DECLARE VARIABLE FTxtMonth CHAR(2);
  DECLARE VARIABLE FMonth  SMALLINT;

  DECLARE VARIABLE FPrefix CHAR(3);
BEGIN
  IF (NEW.CLIENTID IS NULL)
  THEN BEGIN

    IF ((NOT(NEW.BORNDATE IS NULL))AND(NOT(NEW.TEXTCODE IS NULL)))
    THEN BEGIN
      FDay = EXTRACT(DAY FROM NEW.BORNDATE);
      FMonth = EXTRACT(MONTH FROM NEW.BORNDATE);
      IF (fday < 10)
      THEN FTxtDay = '0' || CAST(Fday AS CHARACTER);
      ELSE FTxtDay = CAST(Fday AS CHARACTER);
      IF (FMonth < 10)
      THEN FTxtMonth = '0' || CAST(FMonth AS CHARACTER);
      ELSE FTxtMonth = CAST(FMonth AS CHARACTER);
      NEW.CLIENTID = UPPER(NEW.TEXTCODE) || FTxtDay || FTxtMonth || SUBSTRING(EXTRACT(YEAR FROM NEW.BORNDATE) FROM 3);
    END
    ELSE BEGIN
      IF ((NEW.REGIONID IS NULL)OR(NEW.REGIONID = 0))
      THEN FPrefix = '';
      ELSE BEGIN
        IF (NEW.REGIONID < 10)
        THEN FPrefix = '00';
        ELSE IF (NEW.REGIONID < 100)
             THEN FPrefix = '0';
             ELSE FPrefix = '';
      END
      NEW.CLIENTID = TRIM(FPrefix) || TRIM(NEW.REGIONID) || TRIM(GEN_ID(GEN_CLIENTID,1));
    END
  END
  NEW.TEXTCODE = UPPER(NEW.TEXTCODE);
END

Код: Выделить всё

NEW.CLIENTID = TRIM(FPrefix) || TRIM(NEW.REGIONID) || TRIM(GEN_ID(GEN_CLIENTID,1));
Строка = Строка + целое + целое ? Почему это работает, а вот это:

Код: Выделить всё

NEW.CLIENTID = FPrefix || (CAST(NEW.REGIONID AS CHARACTER))|| CAST(GEN_ID(gen_clientid, 1) AS CHARACTER);
Строка = Строка + Строка + Строка не работает ?

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Re: Ошибка конвертации INTEGER в CHARACTER

Сообщение hvlad » 16 мар 2010, 13:47

CHARACTER - это не строка, это CHAR(1)

Igor321
Сообщения: 3
Зарегистрирован: 16 мар 2010, 11:22

Re: Ошибка конвертации INTEGER в CHARACTER

Сообщение Igor321 » 16 мар 2010, 14:02

CHARACTER - это не строка, это CHAR(1)
Большое спасибо !
Соответственно если я уверен в том что число будет занимать 3 символа, То:

Код: Выделить всё

CAST(NEW.REGIONID AS CHAR(3))

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Re: Ошибка конвертации INTEGER в CHARACTER

Сообщение kdv » 16 мар 2010, 15:37

лучше на авто-преобразование не ориентироваться, и всегда использовать cast.

Ответить