Java 使用cte和变量输入优化SQL查询
我正在尝试使用Java运行下面的SQL脚本,但在没有来自JDBCTemplate的结果集的情况下遇到问题。我考虑过使用函数/存储过程来减少它,并希望得到一些帮助: SQL-第一部分:Java 使用cte和变量输入优化SQL查询,java,sql,sql-server,database,Java,Sql,Sql Server,Database,我正在尝试使用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(
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
我想第一部分可以在存储过程中完成。我确实在这里读过()关于从变量列表生成表的内容,但不确定如何像上面那样在循环中设置这些变量(1,Variable1等)
我想第二部分可以单独完成吗
因此,我更新的查询可能是:
如果有人能帮忙,那就太好了 可以在两个单独的批中执行此操作,但前提是您可以确保第一批在会话范围内运行,而不是在嵌套批中运行(例如通过sp_executesql)。在嵌套批处理中创建的临时表(如存储过程或准备好的语句)会在嵌套批处理结束时自动销毁。所以这取决于你怎么称呼它。我猜事先准备好的声明是行不通的 正确的方法可能是使用带有表值参数、JSON(对于SQL 2016+)或XML参数的存储过程,并在存储过程体中对其进行解析。看 您还可以使用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();
我正在使用SQL server 2012。我实际上试图在jdbc中运行它,但不断出现错误。所以我有点困了。我不知道如何保证临时表不会被破坏?是否可以使用真实的表并更新它,然后删除所有记录?不是最优的,但我不知道如何去做。我如何在可变参数下做到这一点?我前面提到的例子有效吗?谢谢。SQL Server 2012都支持表值参数和XML。如果要保证数据T在那里,我以后如何调用它?我应该使用real table吗?使用TVP的要点是,您可以使用一条语句来发送多行数据并在查询中使用它。