如何逃避“:”在Oracle动态SQL中也有绑定变量?

发布于 2024-10-30 13:06:56 字数 1258 浏览 3 评论 0原文

我正在尝试将以下内容设为动态 SQL,但是 : 字符弄乱了 -

alter session set events 'sql_trace [sql: asasasaass]';

示例:

declare
 l_trc_cmd   varchar2(500);
 l_sql_id    varchar2(500) := 'asasasaass';
begin
  l_trc_cmd     := q'# alter session set events 'sql_trace [sql: :L_SQL_ID]' #';
  execute immediate l_trc_cmd using l_sql_id;
end;
/

以上失败并显示:

ERROR at line 1:
ORA-01006: bind variable does not exist

根据 SQL 语法,需要一个 :,另一个 : 用于绑定变量。

除了连接绑定值之外,还有关于如何解决此问题的任何想法吗?

-- 4 月 4 日下午 5 点 10 分(CST)编辑添加以下内容:

Alter session 不是 DDL 命令。下面是证明。

sqlplus+> select * from t2;

         A
----------
         1

1 row selected.

sqlplus+> insert into t2 values(2);

1 row created.

sqlplus+> alter session set tracefile_identifier ="umappsperf1" statistics_level=all;

Session altered.

sqlplus+> alter session set events 'sql_trace wait=true';

Session altered.

sqlplus+> select * from t2;

         A
----------
         2
         1

2 rows selected.

sqlplus+> rollback;

Rollback complete.

sqlplus+> select * from t2;

         A
----------
         1

1 row selected.

I'm trying to make the following a dynamic SQL, but : character is messing up -

alter session set events 'sql_trace [sql: asasasaass]';

Example:

declare
 l_trc_cmd   varchar2(500);
 l_sql_id    varchar2(500) := 'asasasaass';
begin
  l_trc_cmd     := q'# alter session set events 'sql_trace [sql: :L_SQL_ID]' #';
  execute immediate l_trc_cmd using l_sql_id;
end;
/

Above fails with:

ERROR at line 1:
ORA-01006: bind variable does not exist

One : is required as per syntax of the SQL, and another : is for bind variable.

Any ideas on how to fix this other than concatenating the bind value?

--
Edited on April 4th at 5.10pm CST to add following:

Alter session is not DDL command. Below is proof.

sqlplus+> select * from t2;

         A
----------
         1

1 row selected.

sqlplus+> insert into t2 values(2);

1 row created.

sqlplus+> alter session set tracefile_identifier ="umappsperf1" statistics_level=all;

Session altered.

sqlplus+> alter session set events 'sql_trace wait=true';

Session altered.

sqlplus+> select * from t2;

         A
----------
         2
         1

2 rows selected.

sqlplus+> rollback;

Rollback complete.

sqlplus+> select * from t2;

         A
----------
         1

1 row selected.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

司马昭之心 2024-11-06 13:06:56

对于这个语句,我只是忘记使用绑定变量,例如:

declare
 l_trc_cmd   varchar2(500);
 l_sql_id    varchar2(500) := 'asasasaass';
begin
  l_trc_cmd := REPLACE(
    q'# alter session set events 'sql_trace [sql: %SQLID%]' #'
    ,'%SQLID%',l_sql_id);
  execute immediate l_trc_cmd;
end;
/

For this statement I'd just forget about using a bind variable, e.g.:

declare
 l_trc_cmd   varchar2(500);
 l_sql_id    varchar2(500) := 'asasasaass';
begin
  l_trc_cmd := REPLACE(
    q'# alter session set events 'sql_trace [sql: %SQLID%]' #'
    ,'%SQLID%',l_sql_id);
  execute immediate l_trc_cmd;
end;
/
昔梦 2024-11-06 13:06:56

您不能将绑定变量与 DDL 一起使用:

SQL> exec execute immediate 'CREATE TABLE test AS SELECT :x t FROM DUAL' USING 1;

ORA-01027: bind variables not allowed for data definition operations
ORA-06512: at line 2

此外,您不会收到此有意义的错误消息,因为 : 字符已在语句中转义,因为它们位于引号之间 ('< /代码>)。

You can't use bind variables with DDL:

SQL> exec execute immediate 'CREATE TABLE test AS SELECT :x t FROM DUAL' USING 1;

ORA-01027: bind variables not allowed for data definition operations
ORA-06512: at line 2

In addition, you don't get this meaningful error message because the : characters are already escaped in your statement since they are between quotes (').

南风起 2024-11-06 13:06:56

不能将绑定变量与 DDL 一起使用。对于 PL/SQL 中的 DML,您也不能使用绑定变量,因为当您将值连接到 SQL 语句时它们会自动应用。对 PL/SQL 变量的每个引用实际上都是一个绑定变量。

http://www.akadia.com/services/ora_bind_variables.html

You cannot use bind variables with DDL. With DML in PL/SQL, you cannot use bind variables either because they are automatically applied when you concatenate values to SQL statements. Each reference to a PL/SQL variable is in fact a bind variable.

http://www.akadia.com/services/ora_bind_variables.html

多像笑话 2024-11-06 13:06:56

我还得到了以下解释,与上述答案相关:

您必须使用串联(采用
注意 SQL 注入风险,
当然)。

首先,更改会话集事件
需要一个字符串文字。确实如此
不支持表达式,其中绑定
可以使用变量。

其次,您尝试使用绑定变量
在字符串文字内(嵌入
另一个字符串文字)。绑定
变量不是 SQL*Plus
替换变量(&var 或
&&var)。替代变量是
在任何解析之前由 SQL*Plus 应用
并且他们不识别任何 SQL
句法。他们可以出现在任何地方
任何声明。它们被应用在
客户端不在服务器中。

但是宿主绑定变量是SQL语法
元素。他们被允许作为
操作数(带有特定的 SQL 数据
在 DML、查询中的表达式中键入)
和 PL/SQL 匿名块。他们是
不允许在 DDL 或会话控制中使用
声明。

I was also given following explanation, which correlate with above answers:

You have to use concatenation (taking
care of SQL injection risks, of
course).

First, alter session set events
requires a string literal. It does
not support expressions, where a bind
variable could be used.

Second, you try to use a bind variable
inside a string literal (embedded in
another string literal). Bind
variables are not SQL*Plus
substitution variables (&var or
&&var). Substitution variables are
applied by SQL*Plus before any parsing
and they do not recognize any SQL
syntax. They can come up anywhere in
any statement. They are applied on the
client not in the server.

But host bind variables are SQL syntax
elements. They are allowed as
operands (with a specific SQL data
type) in expressions in DML, queries
and PL/SQL anonymous blocks. They are
not allowed in DDL or session control
statements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文