sql >> データベース >  >> RDS >> Oracle

機能カーソルの割り当て

    必要なもの:

    CREATE OR REPLACE FUNCTION pick_values RETURN t1_prueba_table
        PIPELINED
    IS
        TYPE t2_type IS
            TABLE OF t2%rowtype;
        t2_data   t2_type;
        v_pc      t1.pc%TYPE;
    BEGIN
      -- https://stackoverflow.com/a/67516191/1509264
      -- License: CC BY-SA 4.0
      FOR cur IN (
        SELECT *
        FROM   t1
        ORDER BY pc, r
      ) LOOP
        IF v_pc IS NULL OR v_pc <> cur.pc THEN
          v_pc := cur.pc;
          SELECT *
          BULK COLLECT INTO t2_data
          FROM   t2
          WHERE  pc = cur.pc;
        END IF;
    
        DECLARE
          a_freqs    int_list := int_list();
          cum_freq   INT := 0;
          taken      string_list := split_string(cur.an, ', ');
          idx        INT;
          c          t2.a%TYPE;
          
        BEGIN
          a_freqs.extend(t2_data.count);
          FOR i IN 1..t2_data.count LOOP
            IF     t2_data(i).a = cur.ao
               AND t2_data(i).c > 0
            THEN
              -- If there is an "ao" value and it has capacity then assign it to "c"
              c := t2_data(i).a;
              -- Decrement the appropriate "t2_data" row to show it has been used.
              t2_data(i).c := t2_data(i).c - 1;
              -- Set the "cum_freq" to 0 so the loop where values are randomly assigned is skipped.
              cum_freq := 0;
              -- Exit the loop
              EXIT;
            ELSIF ( 
                    t2_data(i).a = cur.ay
                AND t2_data(i).c > 0
              ) OR (
                    cur.ay IS NULL
                AND t2_data(i).a NOT MEMBER OF taken
                AND t2_data(i).c > 0
              )
            THEN
              a_freqs(i) := cum_freq + t2_data(i).c;
              cum_freq := cum_freq + t2_data(i).c;
            ELSE
              a_freqs(i) := cum_freq;
            END IF;
          END LOOP;
    
          IF cum_freq > 0 THEN
            idx := floor(dbms_random.value(0, cum_freq));
            FOR i IN 1..t2_data.count LOOP
              IF idx < a_freqs(i) THEN
                c := t2_data(i).a;
                t2_data(i).c := t2_data(i).c - 1;
                EXIT;
              END IF;
            END LOOP;
          END IF;
    
          PIPE ROW (
            t1_prueba_data(cur.pc, cur.vk, cur.ay, cur.ao, cur.an, cur.r, c)
          );
        END;
      END LOOP;
    END;
    /
    

    db <> fiddle こちら




    1. リモートMySQL接続を設定する方法

    2. Mac OSX Lion Postgresは、/tmp/.s.PGSQL.5432での接続を受け入れません

    3. すべてのクエリで再接続せずに、PHPでmysqlに効率的に接続するにはどうすればよいですか?

    4. pandasデータフレームを使用してPostgresテーブルの列を更新するにはどうすればよいですか?