【问题标题】:Is it possible to use a variable as a table name in SQL?是否可以在 SQL 中使用变量作为表名?
【发布时间】:2015-02-07 03:51:06
【问题描述】:

我正在使用 Oracle 11g 数据库开发旧版应用程序,并且遇到了一个问题,即我有 5 个表,它们都在不同的模式中,具有相同的数据结构。我需要能够将数据插入这些表中,并且我正在努力避免重复代码。

我知道做如下的事情

IF p_schema = SCHEMA1 THEN 
  INSERT INTO SCHEMA1.TABLE_NAME_SCHEMA1 (...) VALUES (...)
ELSIF p_schema = SCHEMA2 THEN 
  INSERT INTO SCHEMA2.TABLE_NAME_SCHEMA2 (...) VALUES (...)
ELSIF p_schema = SCHEMA3 THEN 
  INSERT INTO SCHEMA3.TABLE_NAME_SCHEMA3 (...) VALUES (...)
ELSIF p_schema = SCHEMA4 THEN 
  INSERT INTO SCHEMA4.TABLE_NAME_SCHEMA4 (...) VALUES (...)
ELSIF p_schema = SCHEMA5 THEN 
  INSERT INTO SCHEMA5.TABLE_NAME_SCHEMA5 (...) VALUES (...)
END IF;

有没有什么办法可以让表名成为 SQL 中的变量,这样我就可以只做一个插入语句,但插入到我想要的表中?

【问题讨论】:

  • 请描述您迄今为止所做的努力和结果。

标签: sql oracle11g sql-insert


【解决方案1】:

你可以吗?当然,使用动态 SQL。你应该?只有 5 个表,我不确定动态 SQL 的额外复杂性是否值得。

p_sql_stmt := 'INSERT INTO ' || p_schema || '.TABLE_NAME (<<columns>>) ' ||
              '  VALUES( ?, ?, ?, ?, ?, ... ? ) ';
EXECUTE p_sql_stmt
  USING val1, val2, val3, val4, ... , valN;

如果您通常都在做这种事情(而不是查看具有这种丑陋 IF 的一段代码),假设您有一个基本的 OLTP 应用程序,那么您正在做很多单-行插入触发器的开销不会很糟糕,我可能会考虑创建一个视图,该视图执行 5 个表的 UNION ALL 以及一个告诉您数据来自哪个表的标识符和一个 @987654324 @ 将INSERT 指向正确表的触发器。然后,您的所有其他代码都可以只引用一个视图,而不是到处都有IF 语句。类似的东西

CREATE VIEW composite_view
AS
SELECT 'Schema1' schema_name, a.*
  FROM schema1.table_name a
UNION ALL
SELECT 'Schema2' schema_name, b.*
  FROM schema2.table_name b
...

INSTEAD OF INSERT 触发器中

IF( :new.schema_name = 'Schema1' ) 
THEN 
  INSERT INTO schema1.table_name( <<columns>> ) 
    VALUES( :new.col1, :new.col2, ... );
ELSIF( :new.schema_name = 'Schema2' ) 
THEN 
  INSERT INTO schema2.table_name( <<columns>> ) 
    VALUES( :new.col1, :new.col2, ... );
...

【讨论】:

    【解决方案2】:

    我认为您可以为此使用insert allinsert first。比如:

    INSERT FIRST
        WHEN p_schema = 'SCHEMA1' THEN INTO SCHEMA1.TABLE_NAME_SCHEMA1( . . . )
        WHEN p_schema = 'SCHEMA2' THEN INTO SCHEMA2.TABLE_NAME_SCHEMA2( . . . )
        . . .
         . . .;
    

    【讨论】:

      【解决方案3】:

      你可以使用动态sql

      declare 
         schema_name varchar2(50);
      begin
         v_name := 'SCHEMA1'; -- set the value of schema, you can do it in a loop also
         execute immediate
            'INSERT INTO '||schema_name ||'.TABLE_NAME_SCHEMA1 (...) VALUES (...)';
         commit; 
      end;
      

      【讨论】:

        【解决方案4】:

        我认为处理这个问题最好的方法是使用procedure,其用法显示here

        CREATE OR REPLACE TYPE employeeType AS OBJECT (employeeId INT, employeeName VARCHAR2(50));
        -- this is how you can use variables
        CREATE TYPE ttEmployeeType AS TABLE OF employeeType;
        
        CREATE PROCEDURE testCustom (pLocation ttEmployeeType)
        AS
        BEGIN
                INSERT
                INTO    employee (emp_id, emp_name)
                SELECT  *
                FROM    TABLE(pLocation);
        END;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-02
          • 2017-10-30
          • 1970-01-01
          • 2019-03-02
          • 2019-02-14
          • 1970-01-01
          • 1970-01-01
          • 2016-01-29
          相关资源
          最近更新 更多