2014-08-28 3 views
2

Я пытаюсь выполнить код PL/SQL с помощью DBD::Oracle. Он запускается без ошибок, но таблицы не удаляются.DBD :: Oracle - блок PL/SQL не работает

Вот код:

my @tabs = qw!actor address category city country customer film film_features 
film_actor film_category film_text inventory language payment rental staff 
store!; 

for my $ts (@tabs){ 

    my $csr = $ora->prepare(q{ 
     DECLARE 
       var_count INT; 
     BEGIN 
      SELECT COUNT(*) INTO var_count 
      FROM sys.all_tables WHERE OWNER = 'SAKILA' AND table_name = :ts ; 
       if var_count > 0 then 
        EXECUTE IMMEDIATE 'DROP TABLE :ts CASCADE CONSTRAINTS' ; 
       end if; 
      END; 
    }); 
    $csr->bind_param(":ts", $ts); 
    $csr->execute; 

} 

ответ

3

№ 1 - Изменение списка таблицы в верхнем регистре

No.2 - Изменение:

ОТ

EXECUTE IMMEDIATE 'DROP TABLE :ts CASCADE CONSTRAINTS' ; 

TO:

EXECUTE IMMEDIATE 'DROP TABLE '||:ts||' CASCADE CONSTRAINTS' ; 

Вот полный код:

my @tabs = qw!ACTOR ADDRESS CATEGORY CITY COUNTRY CUSTOMER FILM FILM_FEATURES FILM_ACTOR FILM_CATEGORY FILM_TEXT INVENTORY LANGUAGE PAYMENT RENTAL STAFF STORE!; 
    for my $ts (@tabs){ 
    chomp $ts; 
    my $csr = $ora->prepare(q{ 
     DECLARE 
      var_count INT; 
     BEGIN 
      SELECT COUNT(*) INTO var_count 
      FROM sys.all_tables WHERE OWNER = 'SAKILA' AND table_name = :ts ; 
      if var_count > 0 then 
       EXECUTE IMMEDIATE 'DROP TABLE '||:ts||' CASCADE CONSTRAINTS' ; 
      end if; 
     END; 
    }); 
$csr->bind_param(":ts", $ts); 
$csr->execute; 
} 
+0

Нет необходимости прописывать имена таблиц в верхнем регистре, oracle sql - это регистр, чувствительный к регистру (если вы явно не говорите ему, что он чувствителен к регистру). – user272735

+1

Если я делаю select на sys.all_tables с именем таблицы = actor, он ничего не возвращает, поэтому условие переводится в false, а таблицы не отбрасываются, но с верхним регистром работает – TonyaLepski

+1

UpperCase необходим для 'table_name = 'SOME_TABLE'', потому что он является строкой, когда она упоминается как сама таблица, дело не имеет значения! И стоит упомянуть, что любой объект DB нельзя использовать как переменную привязки. Вот почему вы создали форму String с именем таблицы, а не привязывали ее. И _bind variable_ для 'DDL' на самом деле - это другое обсуждение! –

2

я заменил бы

EXECUTE IMMEDIATE 'DROP TABLE :ts CASCADE CONSTRAINTS'; 

с

EXECUTE IMMEDIATE 'DROP TABLE '||:ts||' CASCADE CONSTRAINTS'; 

, потому что динамический SQL не распознает :ts как переменную, когда вы поместите его непосредственно в динамический запрос.

+0

Это только исправление одной из двух проблем. @ user3658506 рассмотрел обе проблемы. – user272735

+0

Yup, я не заметил, что имена таблиц не были в верхнем регистре. Затем я бы изменил ': ts' на' UPPER (: ts) 'в' WHERE' и внутри динамического sql-запроса. – yamny

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