【问题标题】:Determine the number of bind vars in a string containing SQL确定包含 SQL 的字符串中绑定变量的数量
【发布时间】:2018-08-26 11:09:26
【问题描述】:

给定一些 SQL 字符串,有没有办法找出其中的绑定变量?例如:

update t set a = :a /* :a is a bind variable */ 
           , b = ':b' -- :b is not a bind variable, as it's inside a string

在字符串中

'update t set a = :a /* :a is a bind variable */ , b = '':b'' -- :b is not a bind variable, as it''s inside a string'

我可以在这个字符串上应用一些描述方法来了解里面有一个绑定变量吗?

首先我考虑在字符串上使用一些 regexp_replace 来删除 cmets 和字符串内容,但这几乎是不可能的,因为冒号可以出现在 cmets 和字符串中,如上所示,但字符串也可以包含 /**/--。所以我打消了这个想法。

需要递归才能正确执行此检测。但与其编写一种递归解析器查询,我希望 Oracle 中有一些内置的东西我可以立即使用:-)

【问题讨论】:

  • 您的意思是,仅仅通过查看 SQL(以字符串形式呈现,无论是 varchar2 还是 clob 数据类型)?为此,您需要某种解析器。一种方法(但这似乎不是您所要求的)是运行查询,此时它将出现在v$sql(您可以从中获得sql_id)和v$sql_bind_capture(通过sql_id) 找到您的查询,您可以在其中计算您的 SQL 语句有多少个绑定变量。
  • @mathguy:是的,正确,我得到了字符串并想知道有多少绑定变量。我想过为查询打开一个 ref_syscursor,然后可能会得到一些描述,但为了做到这一点,我必须知道绑定变量的数量。我尝试不给它绑定变量值,这当然失败了,但我确实在v$sql 中看到了查询。不幸的是,v$sql_bind_capture 中没有任何内容。对我来说是一个很好的解决方案。
  • 您将如何使用这些信息?一个明显的想法(但根据您的实际需要可能会或可能不会起作用)是将 SQL 字符串复制到 SQL Developer 或 Toad 并执行它。在执行任何操作之前,如果有任何绑定变量,系统将提示您输入值,并且您将在那里看到所有绑定变量的列表。 (但请注意,SQL Developer - 我不了解 Toad - 似乎有一个错误,即绑定变量区分大小写!我刚刚在 OTN 上发布了一个关于这个明显错误的问题 - 十年前讨论过,没有更新从那以后,行为没有改变。)
  • @mathguy。感谢您的意见。我正在编写一个通过forall 进行大规模更新的函数。它获取更新 SQL 字符串和包含绑定变量(最多十个)的记录集合。到目前为止,我让调用者告诉我在更新 SQL 字符串中使用了多少绑定变量,但我发现这很多余,并想简单地调查更新字符串 - 或者更确切地说是调查它:-)

标签: sql oracle plsql oracle11g


【解决方案1】:

您可以使用REGEXP_COUNT 来计算替换了 cmets 的字符串中的绑定变量。

例如:

SELECT sqlcode,
REGEXP_COUNT(
 REGEXP_REPLACE(
   REGEXP_REPLACE(
    sqlcode,
    '[/][*].*[*][/]','',1,0,'n'),
    '--.*$','',1,0,'m'),
    '[= ]:\w+', 1, 'i') as TotalBindVars
FROM test;

在 Sql Fiddle 上测试 here

【讨论】:

  • 不起作用:'select * from dual where id=:id and col1 like :x1;' 有两个绑定参数,但您的查询返回一个。
  • @LukeWoodward 现在点赞
  • 绑定变量也可以是函数调用的参数,即WHERE start BETWEEN DATE(:a) AND DATE(:b)。海事组织这是错误的方向
  • 另外,这仍然会匹配注释掉的代码,例如WHERE x = :a /* AND y = :b */
  • 好的,现在首先删除 cmets。并且没有检查绑定变量之前的内容
猜你喜欢
  • 2017-10-05
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 2018-10-18
  • 2020-03-21
  • 1970-01-01
  • 2016-03-11
相关资源
最近更新 更多