Оптимизация SQL-запроса с помощью cte и переменных - PullRequest
0 голосов
/ 27 мая 2019

Я пытаюсь запустить следующий сценарий SQL с использованием Java и получаю проблемы без набора результатов из 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

Я думал, что первую часть можно сделать в магазине.Я читал здесь ( хранимая процедура с переменным числом параметров ) о создании таблицы из списка переменных, но я не уверен, как установить эти переменные в цикле, как я делаю сверху (1,Переменная1 и т. Д.).

Я думаю, что вторая часть может быть сама по себе?

Так что мой обновленный запрос может быть следующим: 1. Вызовите storeprocedure (variable1 ... variablex);2. Sql часть 2?

Если кто-то может помочь, это было бы здорово!

1 Ответ

1 голос
/ 27 мая 2019

Это можно сделать двумя отдельными пакетами, но только если вы можете убедиться, что первый пакет выполняется в области сеанса, а не во вложенном пакете (например, через 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 вместо хранимой процедуры и связать параметр с табличным значением или параметр NVarchar (max), содержащий JSON.

С помощью 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(); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...