SQL实现递归及存储过程中In()参数传递解决方案详解

1.SQL递归

在SQL Server中,我们可以利用表表达式来实现递归算法,一般用于阻止机构的加载及相关性处理。

-->实现:

假设OrganiseUnit(组织机构表)中主要的三个字段为OrganiseUnitID(组织机构主键ID)、ParentOrganiseUnitID(组织机构父ID)、OrganiseName(组织机构名称)


代码如下:

with organise as
(select * from OrganiseUnit where OrganiseUnit.OrganiseUnitID = @OrganiseUnitID
union all select OrganiseUnit.* from organise, OrganiseUnit
where organise.OrganiseUnitID = OrganiseUnit.ParentOrganiseUnitID)

select OrganiseName from organise

上述sql语句实现了, 传入组织机构主键ID,查询出其对应组织机构名称和其 全部下级组织机构名称。

2.存储过程中 In 参数传递

-->情景

① 通过刚才的SQL递归方式,我们已经可以将一个组织机构和其全部下级单位查询出来;假设每个组织机构还有一个字段为OrganiseCode(组织机构代码);

② 当我们需要按照组织机构代码进行筛选数据时,我们会用到 In 这个查询条件,例如select * from OrganiseUnit where OrganiseCode in ('10000001','10000003','10000002')

③但是in()中条件不可能总是固定不变的,有时我们需要用参数传递进去;我们可能会想到设定一个变量参数@OrganiseCode,然后按照'10000001','10000003','10000002'的格式拼参数不就行了吗 ?

④in使用参数时会强制转换参数类型与条件字段一致,不支持构造字符串(如果字段本身为varchar、char型,则in相当于只有一个条件值,而不是一组)

-->实现

①可以使用exec,把整个sql当做参数来执行,例如:exec ('select * from OrganiseUnit where OrganiseCode in ('+@OrganiseCode+')');这样存储过程修改复杂,没有防注功能。

②我们采用另一种方案来解决,先写一个SQL函数,功能是分割字符串


代码如下:

create  function  SplitIn(@c   varchar(2000),@split   varchar(2))  
returns   @t   table(col   varchar(20))  
as  
begin   
  while(charindex(@split,@c)<>0)  
    begin  
      insert   @t(col)   values   (substring(@c,1,charindex(@split,@c)-1))  
      set   @c   =   stuff(@c,1,charindex(@split,@c),'')  
    end  
  insert   @t(col)   values   (@c)  
  return  
end

我们为这个函数传入字符串和分隔符,他就能将字符串按指定符号分割并作为查询结果返回。

例如:执行select col from SplitIn('10000001,10000002,10000003',',')

返回:

10000001

10000002

10000003

③有了这个函数,我们就有了新的解决方案了

定义参数@OrganiseCode,为其传入字符串,这个参数由一个或多个OrganiseCode构成,中间用“,”分割;

调用方式:select * from OrganiseUnit where OrganiseCode in (select col from SplitIn(@OrganiseCode,','))

(0)

相关推荐

  • SQL实现递归及存储过程中In()参数传递解决方案详解

    1.SQL递归 在SQL Server中,我们可以利用表表达式来实现递归算法,一般用于阻止机构的加载及相关性处理. -->实现: 假设OrganiseUnit(组织机构表)中主要的三个字段为OrganiseUnitID(组织机构主键ID).ParentOrganiseUnitID(组织机构父ID).OrganiseName(组织机构名称) 复制代码 代码如下: with organise as(select * from OrganiseUnit where OrganiseUnit.Organ

  • C语言中的参数传递机制详解

    C中的参数传递 本文尝试讨论下C中实参与形参的关系,即参数传递的问题. C语言的参数传递 值传递 首先看下列代码: #include <stdio.h> int main(){ int n = 1; printf("实参n的值:%d,地址:%#x\n", n, &n); void change(int i);//函数声明 change(n); printf("函数调用后实参n的值:%d,地址:%#x\n", n, &n); return

  • Golang中的参数传递示例详解

    前言 本文主要给大家介绍了关于Golang参数传递的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 关于参数传递,Golang文档中有这么一句: after they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution. 函数调用参数均为值传递,不是指针传递或引用传递.经测试引申出来,

  • 浅析SQL Server的嵌套存储过程中使用同名的临时表怪像

    SQL Server的嵌套存储过程,外层存储过程和内层存储过程(被嵌套调用的存储过程)中可以存在相同名称的本地临时表吗?如果可以的话,那么有没有什么问题或限制呢? 在嵌套存储过程中,调用的是外层存储过程的临时表还是自己定义的临时表呢? 是否类似高级语言的变量一样,本地临时表有没有"作用域"范围呢? 注意:也可以称呼为父存储过程和子存储过程,外层存储过程和内层存储过程.这些只是不同的称呼或叫法而已.我们这里统一使用外层存储过程和内层存储过程.后续文章部分不再述说. 我们先来看一个例子,如

  • SQL中的开窗函数详解可代替聚合函数使用

    在没学习开窗函数之前,我们都知道,用了分组之后,查询字段就只能是分组字段和聚合的字段,这带来了极大的不方便,有时我们查询时需要分组,又需要查询不分组的字段,每次都要又到子查询,这样显得sql语句复杂难懂,给维护代码的人带来很大的痛苦,然而开窗函数出现了,曙光也来临了.如果要想更具体了解开窗函数,请看书<程序员的SQL金典>,开窗函数在mysql不能使用. 开窗函数与聚合函数一样,都是对行的集合组进行聚合计算.它用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不

  • java非递归实现之二叉树的前中后序遍历详解

    二叉树的前中后序遍历 核心思想:用栈来实现对节点的存储.一边遍历,一边将节点入栈,在需要时将节点从栈中取出来并遍历该节点的左子树或者右子树,重复上述过程,当栈为空时,遍历完成. 前序遍历 //非递归 //根 左 右 class Solution { public List<Integer> preorderTraversal(TreeNode root) { //用数组来存储前序遍历结果 List<Integer> list = new ArrayList<>(); i

  • 二叉树递归迭代及morris层序前中后序遍历详解

    目录 分析二叉树的前序,中序,后序的遍历步骤 1.层序遍历 方法一:广度优先搜索 方法二:递归 2.前序遍历 3.中序遍历 4.后序遍历 递归解法 前序遍历--递归 迭代解法 前序遍历--迭代 核心思想: 三种迭代解法的总结: Morris遍历 morris--前序遍历 morris--中序遍历 morris--后序遍历: 分析二叉树的前序,中序,后序的遍历步骤 1.层序遍历 方法一:广度优先搜索   (以下解释来自leetcode官方题解) 我们可以用广度优先搜索解决这个问题. 我们可以想到最

  • Jquery中$.ajax()方法参数详解

    俗说好记性不如个烂笔头,下面是jquery中的ajax方法参数详解,这里整理了一些供大家参考. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持. 3.timeout: 要求为Number类型的参数,设置请求超时时间(毫秒).此设置将覆盖$.ajaxSetup()方法的全局设置. 4.async:

  • SQL Server 树形表非循环递归查询的实例详解

    很多人可能想要查询整个树形表关联的内容都会通过循环递归来查...事实上在微软在SQL2005或以上版本就能用别的语法进行查询,下面是示例. --通过子节点查询父节点 WITH TREE AS( SELECT * FROM Areas WHERE id = 6 -- 要查询的子 id UNION ALL SELECT Areas.* FROM Areas, TREE WHERE TREE.PId = Areas.Id ) SELECT Area FROM TREE --通过父节点查询子节点 WIT

  • Java 中Flyway的使用详解

    Flyway的使用 环境:SpringBoot 2.0.4.RELEASE 为什么要用Flyway? 开发人员在合作的时候经常遇到以下场景: 1.开发人员A在自己的本地数据库做了一些表结构的改动,并根据这些改动调整了DAO层的代码,然后将代码上传到svn或git等版本控制服务器上.此时如果开发人员B拉取了A的代码改动,在运行项目的时候很可能会报错,因为B的本地SQL数据库并没有修改. 2.在项目上线的时候,当服务器拉取的版本控制服务器的最新修改后,必须同时运行SQL数据库的修改脚本,如果忘了跑数

随机推荐