1

我想将选择查询结果存储在 PLSQL 中的变量中。

SQL>var v_storedate VARCHAR2(19);
SQL>exec :v_storedate := 'select cdate from rprt where cdate between  cdate AND TO_CHAR(sysdate, 'YYYY/MM/DD-HH24-MI-SS-SSSSS') and ryg='R' and cnum='C002'';

作为

SQL>select cdate from rprt where cdate between  cdate AND TO_CHAR(sysdate, 'YYYY/MM/DD-HH24-MI-SS-SSSSS') and ryg='R' and cnum='C002';

返回 : 2013/04/27-10:06:26:794

但它会引发错误:

 ERROR at line 1: ORA-06550: line 1, column 121: PLS-00103: Encountered
 the symbol "YYYY" when expecting one of the following:
 * & = - + ; < / > at in is mod remainder not rem <an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_ LIKE4_ LIKEC_ between ||
 multiset member SUBMULTISET_ The symbol "*" was substituted for "YYYY"
 to continue. ORA-06550: line 1, column 148: PLS-00103: Encountered the
 symbol ") and ryg=" when expecting one of the following: . ( * @ % & =
 - + ; < / > at in is mod remainder not rem <an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_ LIKE4_ LIKEC_ between
4

4 回答 4

5

如果要存储查询结果,则需要使用select ... into; 目前您正在尝试存储实际查询的文本,而不是其结果。如果您想这样做,则需要像其他答案所指出的那样转义单引号字符,并增加变量大小。

var v_storedate VARCHAR2(19);
exec select cdate into :v_storedate from rprt where cdate between cdate AND TO_CHAR(sysdate, 'YYYY/MM/DD-HH24-MI-SS-SSSSS') and ryg='R' and cnum='C002';
print v_storedate

execute使用普通匿名块而不是 SQL*Plus 的速记更容易处理。在将其转换为字符串时,您还应该给出明确的日期格式掩码:

begin
    select to_char(cdate, 'YYYY/MM/DD-HH24:MI:SS')
    into :v_storedate
    from rprt
    where cdate between cdate AND TO_CHAR(sysdate, 'YYYY/MM/DD-HH24-MI-SS-SSSSS')
    and ryg='R' and cnum='C002';
end;
/

如果你想要小数秒,那么你需要让你的变量更大,因为 19 个字符只会带你到秒。

无论哪种方式,尽管您都冒着获得多个结果(将给出ORA-02112)或没有结果(将给出ORA-01403)的风险。由于您的where子句没有多大意义并且表格内容不知道,我不知道哪个更有可能。正如现在在这里指出的那样,您的cdate比较总是正确的,而且您正在那里进行隐式日期转换,这将在某些时候中断。没有足够的信息来为您解决这个问题。


无论如何,您都无法从日期值中获得小数秒,只能从时间戳中获得;这cdate似乎是。但即便如此,格式元素也是 FF[0-9]。SSSSSS 是自午夜以来的秒数。但由于整体to_char()看起来是错误的,这有点没有实际意义。此外,如果您确实需要与当前时间进行比较,您可能应该比较systimestamp而不是sysdate保持一致 - 然后不要对其进行任何转换。


如果您只想要日期部分:

var v_storedate VARCHAR2(10);
begin
    select to_char(cdate, 'YYYY/MM/DD')
    into :v_storedate
    ...

如果你愿意,你仍然可以使用exec,但是一旦语句变得比你的终端行长度更长,它的可读性就会降低:

var v_storedate VARCHAR2(10);
exec select to_char(cdate, 'YYYY/MM/DD') into :v_storedate from ... where ... ;
于 2013-05-13T07:24:35.170 回答
3

在 PL/SQL 中,使用单引号的更好的方法是引用语法:http ://docs.oracle.com/cd/B28359_01/appdev.111/b28370/fundamentals.htm#CBJJDDCG

begin
  variable := q'#select cdate from rprt where cdate between  cdate AND TO_CHAR(sysdate, 'YYYY/MM/DD-HH24-MI-SS-SSSSS') and ryg='R' and cnum='C002'#'
  ...
end

...或使用匹配的分隔符...

begin
  variable := q'[select cdate from rprt where cdate between  cdate AND TO_CHAR(sysdate, 'YYYY/MM/DD-HH24-MI-SS-SSSSS') and ryg='R' and cnum='C002']'
  ...
end

您也可以在 SQL*Plus 中尝试这样做......不确定它是否在那里工作。

于 2013-05-13T06:18:42.823 回答
0

通过将它们加倍来逃避你的内部撇号!

于 2013-05-13T05:14:57.713 回答
0
  • 将内撇号加倍。
  • 并更改Data Typev_storedateVARCHAR2(140);
于 2013-05-13T05:52:35.440 回答