当前位置: 首页 > 面试题库 >

来自XML的动态查询构造循环条件?

翟博雅
2023-03-14
问题内容

我需要从xml构造我的sql查询的部分条件。

我有一个类似XML:

    <ROOT>
      <PARAMETROS>
        <USU_LOGIN>yleon</USU_LOGIN>
        <USU_NOMBREPRIMERO>Yerusha</USU_NOMBREPRIMERO>
        <USU_APELLIDOPRIMERO>Leon</USU_APELLIDOPRIMERO>
        <USU_EMAIL>yleon@email.com</USU_EMAIL>
        <USU_FECHACREACION>20130510</USU_FECHACREACION>
        <USU_CODICIONES1 TIPO="MC">AND USU_ID=4</USU_CODICIONES1>
        <USU_CODICIONES2 TIPO="MC">AND USU_ID=5</USU_CODICIONES2>
        <USU_CODICIONES3 TIPO="HG">AND USU_ID=9</USU_CODICIONES3>
        ...
        <USU_CODICIONESN TIPO="MC">AND USU_ID=50</USU_CODICIONESN>
      </PARAMETROS>
    </ROOT>

因此,我需要提取属性为TIPO =“ MC”的条件;我使用以下代码:

SELECT txt = T.Item.value('data(.)', 'varchar(255)')
FROM   @xml.nodes('/ROOT/PARAMETROS/*') AS T(Item)
WHERE T.Item.value('data(@TIPO)', 'varchar(255)')='MC'

现在,假设我的查询是:

Select * from USUARIOS
where 1=1 USU_CODICIONES1 USU_CODICIONES2 .. USU_CODICIONESn

我需要替换循环XML的“ @@ USU_CODICIONESX”,但不使用游标,也许要使用cte。

预期结果是:

Select * from USUARIOS
where 1=1 AND USU_ID=4 AND USU_ID=5 .. AND USU_ID=50

问题答案:

您需要动态创建一个SQL语句,然后运行该命令

DECLARE @xml xml =
    '<ROOT>
       <PARAMETROS>
        <USU_LOGIN>yleon</USU_LOGIN>
        <USU_NOMBREPRIMERO>Yerusha</USU_NOMBREPRIMERO>
        <USU_APELLIDOPRIMERO>Leon</USU_APELLIDOPRIMERO>
        <USU_EMAIL>yleon@email.com</USU_EMAIL>
        <USU_FECHACREACION>20130510</USU_FECHACREACION>
        <USU_CODICIONES1 TIPO="MC">AND USU_ID=4</USU_CODICIONES1>
        <USU_CODICIONES2 TIPO="MC">AND USU_ID=5</USU_CODICIONES2>
        <USU_CODICIONES3 TIPO="HG">AND USU_ID=9</USU_CODICIONES3>
        <USU_CODICIONESN TIPO="MC">AND USU_ID=50</USU_CODICIONESN>
      </PARAMETROS>
    </ROOT>'

DECLARE @query nvarchar(max) = 
  'SELECT * FROM USUARIOS where 1=1 USU_CODICIONES1 USU_CODICIONES2 USU_CODICIONESn',
        @dsql nvarchar(max)

;WITH cte AS
 (        
  SELECT T.Item.value('fn:local-name(.)', 'varchar(255)') AS cond,
         T.Item.value('data(.)', 'varchar(255)') AS NewCond,
         ROW_NUMBER() OVER(ORDER BY 1/0) AS rn
  FROM   @xml.nodes('/ROOT/PARAMETROS/*') AS T(Item)  
  WHERE T.Item.value('data(@TIPO)', 'varchar(255)')='MC'
  ), cte2 AS
 (
  SELECT rn, cond, newCond, REPLACE(@query, cond, NewCond) AS NewQuery
  FROM cte
  WHERE rn = 1
  UNION ALL
  SELECT c.rn, c.cond, c.newCond, REPLACE(c2.NewQuery, c.cond, c.NewCond)
  FROM cte c JOIN cte2 c2 ON c.rn = c2.rn + 1
  ) 
  SELECT TOP 1 @dsql = NewQuery
  FROM cte2
  ORDER BY rn DESC

  --PRINT @dsql
  EXEC sp_executesql @dsql

或使用COALESCE /
ISNULL函数进行字符串连接

DECLARE @xml xml =
    '<ROOT>
       <PARAMETROS>
        <USU_LOGIN>yleon</USU_LOGIN>
        <USU_NOMBREPRIMERO>Yerusha</USU_NOMBREPRIMERO>
        <USU_APELLIDOPRIMERO>Leon</USU_APELLIDOPRIMERO>
        <USU_EMAIL>yleon@email.com</USU_EMAIL>
        <USU_FECHACREACION>20130510</USU_FECHACREACION>
        <USU_CODICIONES1 TIPO="MC">AND USU_ID=4</USU_CODICIONES1>
        <USU_CODICIONES2 TIPO="MC">AND USU_ID=5</USU_CODICIONES2>
        <USU_CODICIONES3 TIPO="HG">AND USU_ID=9</USU_CODICIONES3>
        <USU_CODICIONESN TIPO="MC">AND USU_ID=50</USU_CODICIONESN>
      </PARAMETROS>
    </ROOT>'

DECLARE @query nvarchar(max) = 
  'SELECT * FROM USUARIOS where 1=1 USU_CODICIONES1 USU_CODICIONES2 USU_CODICIONESn',
        @dsql nvarchar(max)

  SELECT @dsql = REPLACE(COALESCE(@dsql, @query), 
                         T.Item.value('fn:local-name(.)', 'varchar(255)'),
                         T.Item.value('data(.)', 'varchar(255)'))         
  FROM   @xml.nodes('/ROOT/PARAMETROS/*') AS T(Item)  
  WHERE T.Item.value('data(@TIPO)', 'varchar(255)')='MC'
  --PRINT @dsql
  EXEC sp_executesql @dsql


 类似资料:
  • 大家好,我试着做一个方法来应用条件一个SelectQuery,但我不知道如何通过名称获得字段或通过名称获得表,代码示例... 但字段总是空的... 我怎么解决这个。

  • 现在我扪心自问,是不是有什么“点符号”或者其他什么东西让这个案例变得可有可无。在E。例如:本机SQL我会做一些事情,比如创建一个子查询,并从内部投影中选择所有别名值()。 如果有任何建议,我将不胜感激。

  • 问题内容: 该表表示类别层次结构,层次结构顶部的元素的父ID为NULL。该表如下所示: 我正在尝试做的是建立一个SQL查询,这将使我返回: 任何给定[categoryId]的[categoryId],[categoryName]链。它应该循环并获取每一行,直到到达具有parentId == NULL的行为止。 如上面的示例示例234-> 91-> 35-> 20-> 1-> NULL(STOP)

  • QueryBuilder 提供了一个简便,流畅的 SQL 查询构造器。在不影响代码可读性的前提下用来快速的建立 SQL 语句。 QueryBuilder 在功能上与 ORM 重合, 但是各有利弊。ORM 更适用于简单的 CRUD 操作,而 QueryBuilder 则更适用于复杂的查询,例如查询中包含子查询和多重联结。 使用方法: // User 包装了下面的查询结果 type User stru

  • 简介 在 Swoft 中,数据库查询构造器为创建和执行数据库查询提供了一个方便的接口,它可用于执行应用程序中大部分数据库操作,且可在所有支持的数据库系统上运行。 Swoft 的查询构造器使用 PDO 参数绑定来保护您的应用程序免受 SQL 注入攻击。因此没有必要清理作为绑定传递的字符串。 你可以使用 DB::table('table') 得到一个 Builder 对象,也可以使用 Builder:

  • 简介 Hyperf 的数据库查询构造器为创建和运行数据库查询提供了一个方便的接口。它可用于执行应用程序中大部分数据库操作,且可在所有支持的数据库系统上运行。 Hyperf 的查询构造器使用 PDO 参数绑定来保护您的应用程序免受 SQL 注入攻击。因此没有必要清理作为绑定传递的字符串。 这里只提供一部分常用的教程,具体教程可以到 Laravel 官网查看。 Laravel Query Builde