Ошибка: "PLS-00103: Encountered the symbol TABLE", при запуске анонимного PL/SQL блока с DDL различных таблиц

Запускаю следуюший скрипт:

import cx_Oracle
    
conn = cx_Oracle.connect(user = db_user, password = db_pwd, dsn = 'TULSA').
cur = conn.cursor()

sql = ("""  
        BEGIN
            truncate table shop_ord_temp;
            truncate table shop_ord_item_temp;
            truncate table shop_cust_temp;
        END;
    """)

cur.execute(sql)
cur.close()
conn.close()

Получаю ошибку при запуске анонимного блока:

Traceback (most recent call last):
  File "test.py", line 15, in <module>
    cur.execute(sql)
cx_Oracle.DatabaseError: ORA-06550: line 3, column 22:
PLS-00103: Encountered the symbol "TABLE" when expecting one of the following:
    
       := . ( @ % ;

В чём причиа ошибки, или как сделать лучше?


Свободный перевод вопроса Truncating multiple tables in a Oracle PL/SQL block fails от участника @epipko

Truncating multiple tables in a Oracle PL/SQL block fails


Ответы (2 шт):

Автор решения: 0xdb

Сделайте так:

sql = ("""  
        BEGIN
            execute immediate 'truncate table shop_ord_temp';
            execute immediate 'truncate table shop_ord_item_temp';
            execute immediate 'truncate table shop_cust_temp';
        END;
    """)

Это функция PL/SQL, не имеющая прямого отношения к Python.


Свободный перевод ответа от участника @Christopher Jones

→ Ссылка
Автор решения: 0xdb

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

Поэтому, следующий воспроизводимый пример более лаконичен и удобочитаем:

from cx_Oracle import connect 

conn = connect ('me/me@dbsrv/dbsrvc', encoding="utf-8")
cur = conn.cursor()

tables = ['shop_ord_temp','shop_ord_item_temp','shop_cust_temp']
truncate = 'truncate table '
for table in tables:  
    cur.execute (truncate + table)
print ("tables truncated", len (tables))
cur.close ()
conn.close ()
→ Ссылка