You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将随机姓名生成SQL转为函数/机制填充CUSTOMERS表?

问题描述

我有一段可正常生成随机姓名的Oracle SQL代码,运行逻辑及输出如下:

原SQL代码:

WITH cte AS ( SELECT  level lvl FROM dual CONNECT BY level <= 5 )
        SELECT 
          case t1.lvl
               WHEN 1 THEN 'Faith'
                WHEN 2 THEN 'Tom'
                WHEN 3 THEN 'Anna'
                WHEN 4 THEN 'Lisa'
                WHEN 5 THEN 'Andy'
                end first_name,
         case t1.lvl
              WHEN 1 THEN 'Andrews'
               WHEN 2 THEN 'Thorton'
               WHEN 3 THEN 'Smith'
               WHEN 4 THEN 'Jones'
               WHEN 5 THEN 'Beirs'
               end last_name
   FROM (
   SELECT lvl
    FROM cte
    ORDER BY dbms_random.value(0,sign(lvl))
   ) t1

输出示例:

FIRST_NAME    LAST_NAME
Tom    Thorton
Anna    Smith
Andy    Beirs
Lisa    Jones
Faith    Andrews

FIRST_NAME    LAST_NAME
Lisa    Jones
Anna    Smith
Faith    Andrews
Andy    Beirs
Tom    Thorton

我希望将这段代码转化为可复用机制(比如函数),用来给CUSTOMERS表填充随机姓名。已编写带占位符的PL/SQL循环插入代码,需将'???'替换为随机生成的姓名:

CREATE TABLE CUSTOMERS (
 customer_id NUMBER,
 first_name VARCHAR2 (20),
 last_name VARCHAR2 (20));

begin
      for i in 1 .. 17 loop 
         INSERT into customers (customer_id,  first_name, last_name) 
      VALUES (i, '???', '???');
              end loop;
    end;
/

方案一:创建可复用的随机姓名函数

先定义存储姓名的对象类型,再创建返回随机姓名的函数,方便后续多次调用:

-- 创建存储姓名的对象类型
CREATE OR REPLACE TYPE name_rec IS OBJECT (
    first_name VARCHAR2(20),
    last_name VARCHAR2(20)
);
/

-- 生成随机姓名的函数
CREATE OR REPLACE FUNCTION get_random_name RETURN name_rec IS
    v_first_name VARCHAR2(20);
    v_last_name VARCHAR2(20);
BEGIN
    SELECT first_name, last_name
    INTO v_first_name, v_last_name
    FROM (
        WITH cte AS (SELECT level lvl FROM dual CONNECT BY level <=5)
        SELECT 
            CASE lvl
                WHEN 1 THEN 'Faith'
                WHEN 2 THEN 'Tom'
                WHEN 3 THEN 'Anna'
                WHEN 4 THEN 'Lisa'
                WHEN 5 THEN 'Andy'
            END first_name,
            CASE lvl
                WHEN 1 THEN 'Andrews'
                WHEN 2 THEN 'Thorton'
                WHEN 3 THEN 'Smith'
                WHEN 4 THEN 'Jones'
                WHEN 5 THEN 'Beirs'
            END last_name
        FROM cte
        ORDER BY dbms_random.value -- 简化排序逻辑,直接用随机值排序
    )
    WHERE ROWNUM = 1;
    
    RETURN name_rec(v_first_name, v_last_name);
END;
/

修改插入代码,调用函数获取随机姓名:

CREATE TABLE CUSTOMERS (
 customer_id NUMBER,
 first_name VARCHAR2 (20),
 last_name VARCHAR2 (20));

begin
    for i in 1 .. 17 loop 
        INSERT into customers (customer_id, first_name, last_name) 
        VALUES (i, get_random_name().first_name, get_random_name().last_name);
    end loop;
    COMMIT; -- 务必提交事务
end;
/

方案二:直接嵌入随机逻辑(无需创建函数)

如果不需要长期复用,可直接将随机姓名查询嵌入INSERT语句,省去函数定义步骤:

CREATE TABLE CUSTOMERS (
 customer_id NUMBER,
 first_name VARCHAR2 (20),
 last_name VARCHAR2 (20));

begin
    for i in 1 .. 17 loop 
        INSERT into customers (customer_id, first_name, last_name) 
        SELECT i, first_name, last_name
        FROM (
            WITH cte AS (SELECT level lvl FROM dual CONNECT BY level <=5)
            SELECT 
                CASE lvl
                    WHEN 1 THEN 'Faith'
                    WHEN 2 THEN 'Tom'
                    WHEN 3 THEN 'Anna'
                    WHEN 4 THEN 'Lisa'
                    WHEN 5 THEN 'Andy'
                END first_name,
                CASE lvl
                    WHEN 1 THEN 'Andrews'
                    WHEN 2 THEN 'Thorton'
                    WHEN 3 THEN 'Smith'
                    WHEN 4 THEN 'Jones'
                    WHEN 5 THEN 'Beirs'
                END last_name
            FROM cte
            ORDER BY dbms_random.value
        )
        WHERE ROWNUM = 1;
    end loop;
    COMMIT;
end;
/

方案三:批量插入(高效生成大量数据)

若需插入大量数据,循环插入效率较低,可使用批量生成的方式一次性插入:

CREATE TABLE CUSTOMERS (
 customer_id NUMBER,
 first_name VARCHAR2 (20),
 last_name VARCHAR2 (20));

INSERT INTO customers (customer_id, first_name, last_name)
SELECT 
    rownum,
    CASE TRUNC(dbms_random.value(1,6))
        WHEN 1 THEN 'Faith'
        WHEN 2 THEN 'Tom'
        WHEN 3 THEN 'Anna'
        WHEN 4 THEN 'Lisa'
        WHEN 5 THEN 'Andy'
    END first_name,
    CASE TRUNC(dbms_random.value(1,6))
        WHEN 1 THEN 'Andrews'
        WHEN 2 THEN 'Thorton'
        WHEN 3 THEN 'Smith'
        WHEN 4 THEN 'Jones'
        WHEN 5 THEN 'Beirs'
    END last_name
FROM dual
CONNECT BY level <=17; -- 生成17条数据

COMMIT;

内容的提问来源于stack exchange,提问作者Pugzly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 21:05:26