如何使用PL/SQL中的select语句为SQL*Plus变量赋值?

Bar*_*iss 5 oracle sqlplus

如何使用select语句为变量赋值并在SQL*Plus脚本中使用它,如下所示?

VARIABLE FullCatCode VARCHAR2(7)

exec :FullCatCode := (SELECT CatCode from draw_catcodes where series = 123 and base = 158);

SELECT :FullCatCode || '-' || Other stuff... from table_name...
Run Code Online (Sandbox Code Playgroud)

编辑:@AlexPoole,对于不精确的问题陈述,我们深表歉意.我从280K记录数据集中提取50列数据.我根据来自辅助表(draw_catcodes)的子字符串为每条记录分配序列nextval.我在SQL*Plus中运行SELECT语句,假脱机到CSV文件.SQL现在看起来像这样(测试下面的第二条建议):

COLUMN CatCode NEW_VALUE FullCatCode;

SELECT
(CASE d.image WHEN 0 THEN 'NoImage.pdf'
 ELSE lower(d.prefix || lpad(d.series,3,0) || lpad(d.base,3,0) || lpad(d.suffix,2,0) || lpad(d.rev,2,0) || '.pdf') END) as "Filename",
(SELECT EngDiscipline from draw_catcodes c where d.series = c.series and d.base = c.base) as "EngDiscipline",

(SELECT CatCode from draw_catcodes c where d.series = c.series and d.base = c.base),

SELECT &FullCatCode || '-' ||
lpad((CASE substr(&FullCatCode,0,3)
WHEN 'AEG' THEN (SELECT AEG_seq.NEXTVAL FROM DUAL)
WHEN 'ARY' THEN (SELECT ARY_seq.NEXTVAL FROM DUAL)
WHEN 'BBR' THEN (SELECT BBR_seq.NEXTVAL FROM DUAL)
ELSE 0
END),6,0) as "ItemID",
upper(d.prefix || '-' || lpad(d.series,3,0) || '-' || lpad(d.base,3,0) || '-' || lpad(d.suffix,2,0)) as "LegacyID",
...
from tablename where ...
Run Code Online (Sandbox Code Playgroud)

我开始使用存储函数'Upserted'一个序列表(不能从函数执行DML),尝试使用OUT变量的存储过程(无法从SQL SELECT中调用该过程),现在尝试序列在一个CASE声明中(无法弄清楚如何使用如上所述的变量)...任何建议将不胜感激!

编辑:@AlexPoole,因为变量在这个上下文中不起作用,我只是直接选择我的值,然后使用CASE语句指定正确的序列.但语法不正确,因为我在下一行收到ORA-00933:SQL命令未正确结束错误:

SELECT ((SELECT CatCode from draw_catcodes c where d.series = c.series and d.base = c.base) || '-' ||
lpad((CASE substr((SELECT CatCode from draw_catcodes c where d.series = c.series and d.base = c.base),0,3)
WHEN 'AEG' THEN AEG_seq.NEXTVAL
WHEN 'ARY' THEN ARY_seq.NEXTVAL
WHEN 'BBR' THEN BBR_seq.NEXTVAL
...
WHEN 'SPR' THEN SPR_seq.NEXTVAL
WHEN 'SRL' THEN SRL_seq.NEXTVAL
ELSE 0
END),6,0))  as "ItemID" FROM DUAL,
upper(d.prefix || '-' || lpad(d.series,3,0) || '-' || lpad(d.base,3,0) || '-' || lpad(d.suffix,2,0)) as "LegacyID",
Run Code Online (Sandbox Code Playgroud)

编辑:@AlexPoole,我添加了JOIN并清理了SELECT但现在得到一个ORA-02287:序列号不允许这里

(c.CatCode || '-' || 
(SELECT lpad(
(CASE substr(c.CatCode,0,3)
WHEN 'AEG' THEN AEG_seq.NEXTVAL
WHEN 'ARY' THEN ARY_seq.NEXTVAL
WHEN 'BBR' THEN BBR_seq.NEXTVAL
WHEN 'BSY' THEN BSY_seq.NEXTVAL
...
WHEN 'SDR' THEN SDR_seq.NEXTVAL
WHEN 'SLC' THEN SLC_seq.NEXTVAL
WHEN 'SLD' THEN SLD_seq.NEXTVAL
WHEN 'SMS' THEN SMS_seq.NEXTVAL
WHEN 'SPP' THEN SPP_seq.NEXTVAL
WHEN 'SPR' THEN SPR_seq.NEXTVAL
WHEN 'SRL' THEN SRL_seq.NEXTVAL
ELSE 0 END ),6,0) FROM DUAL)) as "ItemID",
...
FROM md_draw d 
join draw_catcodes c on d.series = c.series and d.base = c.base
order by lpad(d.series,3,0), lpad(d.base,3,0), lpad(d.suffix,2,0);
Run Code Online (Sandbox Code Playgroud)

有什么建议?

编辑:@AlexPoole,你是对的,我在你详细说明时删除了包含序列调用的子查询,但是仍然得到ORA-02287:这里不允许的序列号错误:

SELECT
(CASE d.image WHEN 0 THEN 'NoImage.pdf'
 ELSE lower(d.prefix || lpad(d.series,3,0) || lpad(d.base,3,0) || lpad(d.suffix,2,0) || lpad(d.rev,2,0) || '.pdf') END) as "Filename",
c.EngDiscipline as "EngDiscipline",
c.CatCode || '-' || lpad(CASE substr(c.CatCode,0,3)
WHEN 'AEG' THEN AEG_seq.NEXTVAL
WHEN 'ARY' THEN ARY_seq.NEXTVAL
WHEN 'BBR' THEN BBR_seq.NEXTVAL
...
WHEN 'SPP' THEN SPP_seq.NEXTVAL
WHEN 'SPR' THEN SPR_seq.NEXTVAL
WHEN 'SRL' THEN SRL_seq.NEXTVAL
ELSE 0 END,6,'0') as "ItemID",
upper(d.prefix || '-' || lpad(d.series,3,0) || '-' || lpad(d.base,3,0) || '-' || lpad(d.suffix,2,0)) as "LegacyID",
    ...
FROM md_draw SAMPLE (1) d 
join draw_catcodes c on d.series = c.series and d.base = c.base
order by c.ccProgram, lpad(d.series,3,0), lpad(d.base,3,0), lpad(d.suffix,2,0);
Run Code Online (Sandbox Code Playgroud)

Ale*_*ole 9

这很容易.在PL/SQL查询要么需要一个光标,或者你有选择进入一些; 在这里,进入你的bind变量:

VARIABLE FullCatCode VARCHAR2(7)

exec SELECT CatCode into :FullCatCode from draw_catcodes where series = 123 and base = 158;

SELECT :FullCatCode || '-' || Other stuff... from table_name...
Run Code Online (Sandbox Code Playgroud)

如果您只想在以后的SQL语句中使用它,您也可以使用替换变量,而不是绑定变量:

COLUMN CatCode NEW_VALUE FullCatCode

SELECT CatCode from draw_catcodes where series = 123 and base = 158;

SELECT &FullCatCode || '-' || Other stuff... from table_name...
Run Code Online (Sandbox Code Playgroud)

根据您修改后的问题,这不是您想要做的事情.您试图在同一查询的另一部分中引用子查询中的值,而不是稍后在脚本中单独的语句.而且没有涉及PL/SQL.

你不能用上述任何一种机制做到这一点; 第一个是因为没有PL/SQL块来执行select ... into,第二个因为替换变量在语句运行之前被评估和替换 - new_value直到查询运行之后才存在.

你不想在这里使用子查询,你应该使用一个连接,例如:

SELECT
  CASE d.image WHEN 0 THEN 'NoImage.pdf'
    ELSE lower(d.prefix || lpad(d.series,3,'0') || lpad(d.base,3,'0') || lpad(d.suffix,2,'0') || lpad(d.rev,2,'0') || '.pdf')
    END as "Filename",
  c.EngDiscipline as "EngDiscipline",
  c.CatCode,  -- not sure if you actually want this raw value?
  c.CatCode || '-' || lpad(CASE substr(c.CatCode,0,3)
    WHEN 'AEG' THEN AEG_seq.NEXTVAL
    WHEN 'ARY' THEN ARY_seq.NEXTVAL
    WHEN 'BBR' THEN BBR_seq.NEXTVAL
    ELSE 0
    END,6,'0') as "ItemID",
  upper(d.prefix || '-' || lpad(d.series,3,'0') || '-' || lpad(d.base,3,'0') || '-' || lpad(d.suffix,2,'0'))
    as "LegacyID",
  ...
from tablename d
join draw_catcodes c on d.series = c.series and d.base = c.base
where ...
Run Code Online (Sandbox Code Playgroud)

您可以直接参考c.CatCode您尝试使用的地方&FullCatCode.

如果序列仅存在于此查询中且ItemId没有更广泛的意义,则可以使用分析函数来生成ItemIds:

  c.CatCode || '-' ||
    lpad(row_number() over (partition by substr(c.CatCode,0,3) order by null),6,'0')
    as "ItemID",
Run Code Online (Sandbox Code Playgroud)

ItemIds没有确定性排序,但是没有序列方法; 如果需要,您可以修改窗口子句以指定排序.