Существует ли эквивалент JDFTVAL для SQL?

Для Iseries/IBMi DB2.

Я соединяю несколько файлов/таблиц вместе.

Я написал код как в DDS, так и в SQL.

Логический файл DDS работает точно так, как ожидалось, но я не могу использовать его для встроенного sql в rpgle, так как по умолчанию он использует механизм SQE, что приводит к ужасной производительности.

С другой стороны, в представлении SQL было NULLs, пока я не использовал IFNULL( MBRDESCR, ''). Но теперь MBRDECSR это VARCHAR. Что неприемлемо.

Итак, как мне создать соединение SQL без NULLs и VARCHARs?

Запрошенный пример кода:

ДДС:

                                            JDFTVAL                                              
                R TRANSR                    JFILE(TRANSPF MBRPF)                                

                J                           JOIN(1 2)
                                            JFLD(MBRID MBRID)                                  
      *                                                
                  TRANSID                   JREF(1)     
                  MBRID                     JREF(1)                               
                  MBRNAME                   JREF(2)                               
                  MBRSURNME                 JREF(2)                               
      *                   
                K TRANSID                                                       
                K MBRID

SQL:

CREATE VIEW TRANSV01 AS (                 
    SELECT TRANSID                                 ,
           MBRID                                   ,                 
           CAST(IFNULL(MBRNAME  , '') as Char(20)) ,                 
           CAST(IFNULL(MBRSURNME, '') as Char(25))                  
    FROM TRANSPF
    --Member Name                                                               
    LEFT OUTER JOIN MBRPF on MBRID = MBRID     
) RCDFMT TRANSR;                                                             

Обратите внимание на следующее:

  1. Пример выше упрощен

  2. Не каждый MBRID в TRANSPF имеет соответствующую запись в MBRPF (т. е. нет ссылочного ограничения). Таким образом, когда MBRPF присоединяется к TRANSPF, в MBRNAME, MBRSURNME будут значения NULL. Если не используется JDFTVAL или IFNULL().

  3. Я предпочитаю не иметь VARCHAR из-за производительности и extname() в rpgle.

  4. Я предпочитаю не иметь значений NULL, я не хочу, чтобы pgm их обрабатывал.


person Christoff Erasmus    schedule 28.01.2013    source источник
comment
Я не понимаю всего вопроса. Мне бы помог хотя бы небольшой фрагмент того, что вы сделали в DDS. Я могу помочь вам решить неприемлемую проблему с varchar (хотя я не понимаю, почему это может быть проблемой). Просто используйте CAST(IFNULL(MBRDESCR,'') AS CHAR(50)).   -  person Dennis    schedule 28.01.2013
comment
Я согласен с Денисом. И, пожалуйста, покажите свой существующий код SQL.   -  person    schedule 28.01.2013
comment
Так что, если я правильно прочитал (кроме слишком упрощенного JOIN MBRPF ON MBRID=MBRID, который должен дать вам ошибку, даже если это не так), CAST решает проблему, верно? Или проблемы остались? (Я собирался прокомментировать производительность и комментарий extname(), но решил оставить это. Пожалуйста. :))   -  person Dennis    schedule 28.01.2013
comment
@ Деннис, верно, CAST действительно решает проблему. Также JOIN (M = M) вызовет ошибку.   -  person Christoff Erasmus    schedule 29.01.2013


Ответы (1)


Предполагая, что это «Разрешает нулевое значение», которое вы считаете нежелательным, используйте UNION. Первый SELECT выбирает все совпадающие строки, которые устанавливают для вас свойство NOT NULL. Второй SELECT выбирает все строки, у которых нет совпадений — для них вы предоставляете поля-заполнители.

CREATE VIEW TRANSV01 AS (                 
    SELECT TRANSID                                 ,
           MBRID                                   ,                 
           MBRNAME  ,
           MBRSURNME
    FROM TRANSPF
    --Member Name                                                               
    JOIN MBRPF on MBRID = MBRID     
  UNION
    SELECT TRANSID                                 ,
           MBRID                                   ,                 
           CAST('') as Char(20)) ,                 
           CAST('') as Char(25))                  
    FROM TRANSPF
    --Member Name                                                               
    EXCEPTION JOIN MBRPF on MBRID = MBRID     
) RCDFMT TRANSR;                                             
person Buck Calabro    schedule 28.01.2013
comment
То есть, если MBRNAME и/или MBRSURNME не имеют нулевых значений. Тогда это не даст нужного эффекта. - person Dennis; 28.01.2013
comment
Истинный! Однако, если бы OP использовал ALWNULL в DDS, он, вероятно, не беспокоился бы о SQL «Разрешает нулевое значение». Если бы действительно были нулевые значения, ему понадобились бы дополнительные UNION для их индивидуальной обработки. Уродливый? Уверенный. Хорошая причина принять тот факт, что в реляционной базе данных есть пустые значения, и начать обрабатывать их в кодовой базе, а не прилагать уродливые усилия, чтобы заставить их исчезнуть. - person Buck Calabro; 28.01.2013
comment
@BuckCalabro, спасибо. Обработка в коде есть. - person Christoff Erasmus; 29.01.2013
comment
@BuckCalabro это особенно важно при работе с несколькими поставщиками. Например, в Oracle нет разницы между '' (без пробелов между ними) и NULL. Иными словами, для этого механизма БД пустая строка ЯВЛЯЕТСЯ NULL. Нет конца разочарованию, которое вызывает у меня. И они, кажется, думают, что так и должно быть; это не ошибка. Например: ‹‹WHERE SOMECOLUMN = '' OR SOMECOLUMN ‹› ''›› гарантированно никогда не совпадет, поскольку ничто никогда не равно, больше или меньше NULL. Даже не NULL. - person Dennis; 29.01.2013