Oracle C# 中解释计划的参数化查询

问题描述 投票:0回答:2

我有一个解释计划查询,我需要在 .Net 应用程序中使用参数进行调用。当我尝试如下时,它给出了 ORA-1780 错误。我的应用程序中有许多参数化查询,但此脚本不起作用。我该如何解决它?

private static readonly string sql =@"EXPLAIN PLAN SET STATEMENT_ID = :statementId FOR :sqlScript";

  using (OracleCommand cmd1 = new OracleCommand(PrepareCostOracleSqlPattern, con))
  {
                        cmd1.Parameters.Add(new OracleParameter("statementId", statementId));
                        cmd1.Parameters.Add(new OracleParameter("sqlScript", sqlScript));
                        cmd1.CommandTimeout = 6000;
                        object result = cmd1.ExecuteNonQuery();
  }

ORA-01780:需要字符串文字

c# sql .net oracle
2个回答
0
投票

您似乎在

EXPLAIN PLAN
语句中使用绑定变量。 Oracle 不允许在
EXPLAIN PLAN
语句的参数中使用绑定变量,类似于 DDL 中不能使用绑定的方式。绑定仅适用于 SQL(选择和 DML)和 PL/SQL。

所以,不要使用

:
和添加参数,而是使用C#约定简单地使用字符串连接来拼接语句id和SQL语句。您不会希望使用可执行 SQL 来执行此操作,但对于解释计划或偶尔的 DDL 等特殊情况来说这是很好的。


0
投票

EXPLAIN PLAN
不适用于参数化查询;相反,您需要使用字符串连接来构建查询:

类似(未经测试,但您应该了解总体思路):

private static readonly string sql =@"EXPLAIN PLAN SET STATEMENT_ID = '{0}' FOR {1}";

using (OracleCommand cmd1 = new OracleCommand(String.Format(sql, statementId, sqlScript), con))
{
  cmd1.CommandTimeout = 6000;
  object result = cmd1.ExecuteNonQuery();
}

您可以使用

EXECUTE IMMEDIATE
在 SQL 中复制问题(和解决方案),尝试使用绑定变量和字符串连接的组合:

DECLARE
  v_sql VARCHAR2(4000) := 'SELECT * FROM DUAL';
  v_id  PLS_INTEGER    := 42;
BEGIN
  EXECUTE IMMEDIATE 'EXPLAIN PLAN SET STATEMENT_ID = :1 FOR :2'
    USING v_id, v_sql;
END;
/

失败:

ORA-01780: string literal required
ORA-06512: at line 5

连接SQL语句:

DECLARE
  v_sql VARCHAR2(4000) := 'SELECT * FROM DUAL';
  v_id  PLS_INTEGER    := 42;
BEGIN
  EXECUTE IMMEDIATE 'EXPLAIN PLAN SET STATEMENT_ID = :1 FOR ' || v_sql
    USING v_id;
END;
/

也失败,因为语句 id 需要文字:

ORA-01780: string literal required
ORA-06512: at line 5

使用文字作为语句 id:

DECLARE
  v_sql VARCHAR2(4000) := 'SELECT * FROM DUAL';
  v_id  PLS_INTEGER    := 42;
BEGIN
  EXECUTE IMMEDIATE 'EXPLAIN PLAN SET STATEMENT_ID = ''' || v_id || ''' FOR :1'
    USING v_sql;
END;
/

也会失败,因为 SQL 语句也需要连接:

ORA-00905: missing keyword
ORA-06512: at line 5

连接两者:

DECLARE
  v_sql VARCHAR2(4000) := 'SELECT * FROM DUAL';
  v_id  PLS_INTEGER    := 42;
BEGIN
  EXECUTE IMMEDIATE 'EXPLAIN PLAN SET STATEMENT_ID = ''' || v_id || ''' FOR ' || v_sql;
END;
/
1 rows affected

有效。

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.