Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在oracle存储过程中创建和执行动态查询?_Sql_Oracle_Stored Procedures - Fatal编程技术网

Sql 如何在oracle存储过程中创建和执行动态查询?

Sql 如何在oracle存储过程中创建和执行动态查询?,sql,oracle,stored-procedures,Sql,Oracle,Stored Procedures,我需要在存储过程中动态创建和执行查询 我有两个表用户和用户更新 员工表有emp\u id、用户名、部门、产品、地区、职务等。 员工更新包括emp\u id、生效日期、列名称、新值等列。 基本上这就是我想做的 获取在给定生效日期的用户自定义表中有更新的所有员工 对每个员工进行循环 获取给定生效日期内每个员工的所有更新。在employee_updates表中,员工可能有一个或多个更新 基于这些更新创建动态“更新”查询,如 更新员工集合col1=new\u val\u 1,col2=new\u

我需要在存储过程中动态创建和执行查询

我有两个表用户和用户更新

员工表有
emp\u id、用户名、部门、产品、地区、职务等。

员工更新包括
emp\u id、生效日期、列名称、新值等列。

基本上这就是我想做的

  • 获取在给定生效日期的用户自定义表中有更新的所有员工

  • 对每个员工进行循环

  • 获取给定生效日期内每个员工的所有更新。在employee_updates表中,员工可能有一个或多个更新

  • 基于这些更新创建动态“更新”查询,如

    更新员工集合col1=new\u val\u 1,col2=new\u val\u 2,其中emp\u id=?

  • 这就是我到目前为止所做的

        create or replace
    PROCEDURE SP_RUN_EMPLOYEE_UPDATES 
    (
      IN_DATE IN DATE
    ) 
      IS
          
        update_sql varchar2(225); 
          
    employee_id BI_EMPLOYEE_UPDATE.employee_id%TYPE;   
    
        CURSOR  employees 
            IS   SELECT distinct(employee_id)
                   FROM BI_EMPLOYEE_UPDATE 
                 WHERE EFFECTIVE_DATE = to_date(IN_DATE,'dd-mm-yy') 
                  AND EXECUTED = 'N' AND ACTIVITY_ID = '0'
                  ;
       
        CURSOR e_updates 
        IS  SELECT * 
             FROM BI_EMPLOYEE_UPDATE 
            WHERE EFFECTIVE_DATE = to_date(IN_DATE,'dd-mm-yy') 
             AND EXECUTED = 'N' 
             AND ACTIVITY_ID = '0' 
             and employee_id = employee_id ;
          
         BEGIN
          
       OPEN employees;
       LOOP
        FETCH employees into employee_id;
            EXIT WHEN employees%NOTFOUND;
                
               FOR e_update in e_updates
             update_sql :=  'UPDATE BI_EMPLOYEE SET ';
                  LOOP
                    -- create dynam,ic update statment
                 
                     UPDATE BI_EMPLOYEE_UPDATE
                     SET EXECUTED = 'Y'
                     WHERE EMPLOYEE_UPDATE_ID = e_update.EMPLOYEE_UPDATE_ID ;
                    
                    END LOOP;
                
                -- run dynamic sql 
         
                  END LOOP;
     CLOSE employees;
    END;
    

    请提供帮助。

    您在这里遇到了一些问题,包括:

    • IN\u DATE
      被声明为日期,因此您无需将其通过
      传递到\u DATE()
    • 您只需要一个游标循环;如果出于某种原因希望同时处理
      员工id
      的所有更新,则可以添加
      order by
      子句
    • 您根本不需要动态SQL;可以将光标中的值用作静态SQL更新的一部分
    因此,具有单个循环的简单版本可能类似于:

    CREATE OR REPLACE PROCEDURE sp_run_employee_updates (p_date IN DATE) IS
        CURSOR c_updates IS
            SELECT *
            FROM bi_employee_update
            WHERE effective_date = p_date
            AND executed = 'N' 
            AND activity_id = '0'
            FOR UPDATE;     
    BEGIN
        -- loop around all pending records
        FOR r_update IN c_updates LOOP
            -- apply this update to the bi_employee record
            UPDATE bi_employee
            SET col1 = r_update.col1, col2 = r_update.col2
            WHERE emp_id = r_update.employee_id;
    
            -- mark this update as executed
            UPDATE bi_employee_update
            SET executed = 'Y'
            WHERE CURRENT OF c_updates;
        END LOOP;
    END sp_run_employee_updates;
    
    这是使用
    for update
    where current of
    构造来锁定正在使用的行并简化更新;请参阅文档


    值得注意的是,如果
    effective_date
    p_date
    中有一个时间分量,它们将不匹配。
    p\u date
    不太可能,但是
    effective\u date
    更难猜测。如果确实如此,则您需要
    trunc()
    it,或者使用
    between
    查找时间范围。

    这里有一些问题,包括:

    • IN\u DATE
      被声明为日期,因此您无需将其通过
      传递到\u DATE()
    • 您只需要一个游标循环;如果出于某种原因希望同时处理
      员工id
      的所有更新,则可以添加
      order by
      子句
    • 您根本不需要动态SQL;可以将光标中的值用作静态SQL更新的一部分
    因此,具有单个循环的简单版本可能类似于:

    CREATE OR REPLACE PROCEDURE sp_run_employee_updates (p_date IN DATE) IS
        CURSOR c_updates IS
            SELECT *
            FROM bi_employee_update
            WHERE effective_date = p_date
            AND executed = 'N' 
            AND activity_id = '0'
            FOR UPDATE;     
    BEGIN
        -- loop around all pending records
        FOR r_update IN c_updates LOOP
            -- apply this update to the bi_employee record
            UPDATE bi_employee
            SET col1 = r_update.col1, col2 = r_update.col2
            WHERE emp_id = r_update.employee_id;
    
            -- mark this update as executed
            UPDATE bi_employee_update
            SET executed = 'Y'
            WHERE CURRENT OF c_updates;
        END LOOP;
    END sp_run_employee_updates;
    
    这是使用
    for update
    where current of
    构造来锁定正在使用的行并简化更新;请参阅文档

    值得注意的是,如果
    effective_date
    p_date
    中有一个时间分量,它们将不匹配。
    p\u date
    不太可能,但是
    effective\u date
    更难猜测。如果是这样,那么您需要
    trunc()
    it,或者使用
    between
    查找时间范围。

    适用于在运行时之前不知道SQL将是什么样子的情况。这里的情况似乎不是这样,所以我认为这个词有误导性。直到运行时才知道这些值,但这很正常。你有什么具体问题?我看到的第一个问题是,变量的名称与列的名称相同,这充其量是令人困惑的,并且可能会产生意外的结果。但无论如何,这种方法似乎很奇怪;您将多次更新每个
    员工
    ?为什么是两个循环?用于在运行时之前不知道SQL将是什么样子的情况。这里的情况似乎不是这样,所以我认为这个词有误导性。直到运行时才知道这些值,但这很正常。你有什么具体问题?我看到的第一个问题是,变量的名称与列的名称相同,这充其量是令人困惑的,并且可能会产生意外的结果。但无论如何,这种方法似乎很奇怪;您将多次更新每个
    员工
    ?为什么是两个循环?