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

时间:2016-03-23 22:03:26

标签: 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...
编辑:@AlexPoole,对于不精确的问题陈述,我们深表歉意。我从280K记录数据集中提取50列数据。我根据来自辅助表(draw_catcodes)的子字符串为每条记录分配序列nextval&#s。我在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 ...

我从一个存储功能开始,该功能已经上传了#39;一个序列表(不能从函数执行DML),尝试使用OUT变量的存储过程(无法从SQL SELECT中调用该过程),现在尝试CASE语句中的序列(可以& #39;弄清楚如何使用如上所述的变量)...任何建议都将非常感谢!

编辑:@AlexPoole,由于变量在这个上下文中不起作用,我只是直接选择值I,然后使用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",
编辑:@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);

有什么建议吗?

编辑:@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);

1 个答案:

答案 0 :(得分:6)

这很容易。在PL / SQL中,查询需要是游标,或者您必须选择 into ;在这里,进入你的绑定变量:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    var arrays = values
        .OfType<Array>()
        .Select(x => x.OfType<object>())
        .ToList();
    if (arrays.Count != 2) return DoubleCollectionWhenValueIsNull;
    return arrays[0].SequenceEqual(arrays[1]) ? DoubleCollectionWhenEqual : DoubleCollectionWhenNotEqual;
}

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

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...

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

你不能用上述任何一种机制做到这一点;第一个因为没有PL / SQL块来执行COLUMN CatCode NEW_VALUE FullCatCode SELECT CatCode from draw_catcodes where series = 123 and base = 158; SELECT &FullCatCode || '-' || Other stuff... from table_name... ,第二个因为替换变量在语句运行之前被评估和替换 - 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 ... 的地方的c.CatCode

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

&FullCatCode

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