2010-03-22 5 views
0

Мне нужно создать некоторые операторы обновления, основанные на таблице в нашей базе данных. Я создал следующий скрипт, который генерирует нужные мне обновления. Но когда я пытаюсь запустить эти сценарии, я получаю ошибки, связанные с невыложенными одинарными кавычками в контенте и & B, & Т-символами, которые имеют особое значение в оракуле. Я позаботился о проблемах & B и & T, установив SET DEFINE OFF. Какой лучший способ избежать одиночных кавычек в контенте?Oracle 10g - лучший способ избежать одиночных кавычек

DECLARE 
    CURSOR C1 IS 
     SELECT * FROM EMPLOYEES; 

BEGIN 
    FOR I IN C1 
    LOOP 
     DBMS_OUTPUT.PUT_LINE('UPDATE EMPLOYEES SET 
      FIRST_NAME= ''' || I.FIRST_NAME|| ''', 
      LAST_NAME = ''' || I.LAST_NAME ''', 
      DOB = ''' || I.DOB|| ''' 
      WHERE EMPLOYEE_ID = ''' || I.EMPLOYEE_ID || ''';'); 
    END LOOP; 
END;     

Здесь, если first_name или last_name содержит одинарные кавычки, тогда сгенерированные операторы обновления ломаются. Каков наилучший способ избежать этих одиночных кавычек в first_name и last_name?

ответ

1

Вы можете использовать REPLACE:

DECLARE 
    CURSOR C1 IS 
     SELECT * FROM EMPLOYEES; 

BEGIN 
    FOR I IN C1 
    LOOP 
     DBMS_OUTPUT.PUT_LINE('UPDATE EMPLOYEES SET 
      FIRST_NAME= ''' || REPLACE(I.FIRST_NAME,'''','''''') || ''', 
      LAST_NAME = ''' || REPLACE(I.LAST_NAME,'''','''''') || ''', 
      DOB = TO_DATE(''' || TO_CHAR(I.DOB,'DD/MM/YYYY') || '',''DD/MM/YYYY'')' 
      WHERE EMPLOYEE_ID = ' || I.EMPLOYEE_ID || ';'); 
    END LOOP; 
END; 

Примечания:

  • Вы пропускали || после I.LAST_NAME.
  • Я предполагаю, что I.EMPLOYEE_ID - это число - в этом случае я бы не стал его окружать кавычками.
  • Я предполагаю, что I.DOB - это дата - в этом случае я рекомендую вам явно указать ее на дату.

АЛЬТЕРНАТИВА: Если вы на Oracle 10g или более поздней версии, вы можете использовать этот альтернативный синтаксис, который может быть более удобным для чтения; и использовать REPLACE, чтобы сделать его немного более очевидным, что происходит - это мои личные предпочтения:

DECLARE 
    CURSOR C1 IS 
     SELECT * FROM EMPLOYEES; 

BEGIN 
    FOR I IN C1 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(REPLACE(REPLACE(REPLACE(REPLACE(
     q'[UPDATE EMPLOYEES SET 
      FIRST_NAME= q'{#FIRST_NAME#}', 
      LAST_NAME = q'{#LAST_NAME#}', 
      DOB = DATE '#DOB#' 
      WHERE EMPLOYEE_ID = #EMPLOYEE_ID#; 
      ]' 
      ,'#FIRST_NAME#', I.FIRST_NAME) 
      ,'#LAST_NAME#', I.LAST_NAME) 
      ,'#DOB#', TO_CHAR(I.DOB,'YYYY-MM-DD')) 
      ,'#EMPLOYEE_ID#', I.EMPLOYEE_ID) 
      ); 
    END LOOP; 
END; 

выше, имеет преимущество, что легко обнаружить возможные ошибки в динамическом SQL, которая не проверяется время компиляции для синтаксических ошибок.

+0

@Jeffrey: Спасибо за отзыв. Единственный недостаток этого подхода я вижу в том, что с помощью значений NULL я имею в виду, что first_name в таблице было NULL, используя REPLACE (I.FIRST_NAME, '' '', '' '' ''), мы вставляя пустую строку в таблицу, которая, я думаю, не совпадает с NULL. Не так ли? На данный момент, хотя его более подробный, я использовал IF..ELSE для проверки NULL, и если бы я не использовал q '(I.first_name) и так далее. Работает. Еще раз спасибо за отзывы. – Dharam

+0

№ В Oracle пустая строка такая же, как NULL. –

+0

Альтернатива с Q-кавычками является неполной. Одиночные кавычки останутся невыполненными в сгенерированных операциях обновления. Вам нужно будет использовать Q-кавы внутри, чтобы также обтекать текстовые столбцы _and_ разными разделителями. например. '' # FIRST_NAME # ''должно быть' q {' # FIRST_NAME # '} ' –

Смежные вопросы