Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用cte和变量输入优化SQL查询_Java_Sql_Sql Server_Database - Fatal编程技术网

Java 使用cte和变量输入优化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(

我正在尝试使用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
我想第一部分可以在存储过程中完成。我确实在这里读过()关于从变量列表生成表的内容,但不确定如何像上面那样在循环中设置这些变量(1,Variable1等)

我想第二部分可以单独完成吗

因此,我更新的查询可能是:

  • 调用存储过程(variable1,…,variablex)
  • SQL第2部分

  • 如果有人能帮忙,那就太好了

    可以在两个单独的批中执行此操作,但前提是您可以确保第一批在会话范围内运行,而不是在嵌套批中运行(例如通过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的要点是,您可以使用一条语句来发送多行数据并在查询中使用它。