我正在尝试使用Java运行以下SQL脚本,并且从JDBCTemplate获得没有结果集的问题。我考虑过使用函数/存储过程来减少它,并希望获得一些帮助:
SQL:
第一部分:
SET NOCOUNT ON
IF OBJECT_ID('tempdb.dbo.#tempSearch', 'U') IS NOT NULL
DROP TABLE #tempSearch;
CREATE TABLE #tempSearch
(
ID int,
Value VARCHAR(255)
)
INSERT INTO #tempSearch
VALUES(1,'Variable1'),
(2,'Variabl2');
第二部分:
with cte as (
select RoleID,','+replace(replace(GroupNames,',',',,'),' ','')+',' GroupNames from UserGroup_Role_Mapping
)
,cte2 as(
select cte.RoleID, replace(cte.GroupNames,','+Value+',','') as GroupNames, s.ID, s.Value
from cte
join #tempSearch s on ID=1
union all
select cte2.RoleID, replace(cte2.GroupNames,','+s.Value+',','') as l, s.ID ,s.Value
from cte2
join #tempSearch s on s.ID=cte2.ID+1
)
SELECT a.Role, a.Sort_Order, a.Parent, a.Parent_ID, a.Parent_URL, a.Child, a.Child_ID,a.Child_URL
FROM Config_View a
WHERE a.Role IN (
Select Name from (
Select distinct RoleID from cte2 where len(GroupNames)=0
) tempRoles
join User_Role
on tempRoles.RoleID = User_Role.ID
)
DROP TABLE #tempSearch
我当时认为第一部分可以在存储过程中完成。我确实在这里(stored procedure with variable number of parameters读过关于用变量列表制作表格的信息,但不确定如何像我从上面那样(1,Variable1等)那样在循环中设置这些变量。
我认为第二部分可以单独存在吗?
所以我更新的查询可能是: 1.调用storeprocedure(variable1 ... variablex); 2. SQL第2部分?
如果有人可以帮助,那就太好了!
答案 0 :(得分:1)
可以在两个单独的批次中执行此操作,但是前提是您可以确保第一个批次在会话范围内运行,而不在嵌套的批次中运行(例如,通过sp_executesql)。在嵌套批处理中创建的临时表(如存储过程或预准备语句)会在嵌套批处理结束时自动销毁。因此,这取决于您如何称呼它。我的猜测是,PreparedStatement无法正常工作。
执行此操作的正确方法可能是使用具有表值参数或JSON(对于SQL 2016+)或XML参数的存储过程,然后在存储过程主体中对其进行解析。参见https://docs.microsoft.com/en-us/sql/connect/jdbc/using-table-valued-parameters?view=sql-server-2017
您还可以使用TSQL批处理而不是存储过程并绑定表值参数或包含JSON的NVarchar(max)参数。
使用TVP,您可以简单地使用以下批处理:
with s as (
select * from ? --bind a table-valued parameter here
), cte as (
select RoleID,','+replace(replace(GroupNames,',',',,'),' ','')+',' GroupNames from UserGroup_Role_Mapping
)
,cte2 as(
select cte.RoleID, replace(cte.GroupNames,','+Value+',','') as GroupNames, s.ID, s.Value
from cte
join s on ID=1
union all
select cte2.RoleID, replace(cte2.GroupNames,','+s.Value+',','') as l, s.ID ,s.Value
from cte2
join s on s.ID=cte2.ID+1
)
SELECT a.Role, a.Sort_Order, a.Parent, a.Parent_ID, a.Parent_URL, a.Child, a.Child_ID,a.Child_URL
FROM Config_View a
WHERE a.Role IN (
Select Name from (
Select distinct RoleID from cte2 where len(GroupNames)=0
) tempRoles
join User_Role
on tempRoles.RoleID = User_Role.ID
)
这将是字符串变量sql
的值,然后将其命名为:
SQLServerPreparedStatement pStmt = (SQLServerPreparedStatement) connection.prepareStatement(sql);
pStmt.setStructured(1, "dbo.CategoryTableType", sourceTVPObject);
ResultSet rs = stmt.executeQuery();