【问题标题】:Replace SELECT INTO Clause with INSERT INTO将 SELECT INTO 子句替换为 INSERT INTO
【发布时间】:2013-03-20 06:24:45
【问题描述】:

以下是为搜索商店中的商品而编写的存储过程。它在 SQL Server 2008 中运行良好。但是当我在 SQL Azure 中运行它时,我发现不支持 SELECT INTO。

我决定使用CREATE #Table 并使用INSERT INTO(Col) Values()

问题是列数是根据搜索条件动态变化的。以下过程中的示例是DISTANCE 列。仅当用户选择城市时才会返回。

如何在以下过程中将 CREATE TABLE 和 INSERT INTO 与动态 SQL 一起使用?

CREATE PROCEDURE [dbo].[SearchItems]
(
 @ShopId INT
,@unitItems INT = 20
,@sortOrder INT = 0
,@language CHAR(2) = 'EN'
,@catId INT
,@search NVARCHAR(100) = ''
,@cityId INT = 0
,@page INT
,@currentDate DATETIME2(0)
,@currentUserId INT = 0
,@itemType TINYINT = 0
,@unitRows INT OUTPUT
,@unitPages INT OUTPUT
)
AS
BEGIN
SET XACT_ABORT ON
SET NOCOUNT ON

DECLARE @sql NVARCHAR(MAX)
        ,@sqlSelect NVARCHAR(MAX) = ''
        ,@sqlTempTable NVARCHAR(MAX) = 'itemSearch'
        ,@sqlInto NVARCHAR(MAX) = ''
        ,@sqlFrom NVARCHAR(MAX) = ''
        ,@sqlClause NVARCHAR(MAX) = ''
        ,@sqlGroup NVARCHAR(MAX) = ''
        ,@params NVARCHAR(MAX)
        ,@sortOrderString NVARCHAR(MAX) = 'ORDER BY IT.CREATEDATE DESC'


SET @sqlSelect =
    'SELECT     
                 IT.ITEMId
                ,IT.USERId
                ,IT.ShopId
                ,IT.ITEMID
                ,IT.ITEMNAME                    
                ,IT.LASTUPDATED

                ,CY.COUNTRYNAME AS COUNTRYNAME
                ,CI.CITYNAME AS CITY
                ,ROW_NUMBER() OVER (' + @sortOrderString + ') AS RowNumber'

SET @sqlGroup =
    ' GROUP BY  IT.ITEMId
                ,IT.USERId
                ,IT.ShopId
                ,IT.ITEMID
                ,IT.ITEMNAME                    
                ,IT.LASTUPDATED                 
                ,CY.COUNTRYNAME
                ,CI.CITYNAME'

SET @sqlFrom =
    ' FROM      dbo.ITEM AS IT
    INNER JOIN  dbo.Shop AS J
            ON  IT.ShopId = J.ShopId
    INNER JOIN  dbo.CITY AS CI
            ON  CI.CITYID = J.CITYID
    INNER JOIN  dbo.COUNTRY AS CY
            ON  CI.COUNTRYISO = CY.COUNTRYISO
    INNER JOIN  dbo.REGION AS R
            ON  CI.REGIONId = R.REGIONId'

    IF (@cityId > 0)
    BEGIN
        SET @sqlFrom = @sqlFrom +
            ' INNER JOIN    dbo.CITY AS CI2
                        ON  CI2.CITYID = @cityId'       
        SET @sqlSelect = @sqlSelect +
            ',dbo.GetDistance(CI2.LATITUDE) AS DISTANCE '       
        SET @sqlGroup = @sqlGroup +
            ',CI2.LATITUDE'
    END

    SET @sqlInto = ' INTO ' + @sqlTempTable + ' ';      
    SET @sql =  @sqlSelect +
                @sqlInto +
                @sqlFrom +
                @sqlClause +
                @sqlGroup

END

有任何帮助/建议吗?

【问题讨论】:

    标签: sql-server sql-server-2008 azure-sql-database


    【解决方案1】:

    您的临时表也需要动态创建,否则,它不在同一上下文中,它将返回您的临时表未定义错误。基本上,您执行以下操作: 添加如下参数

    
    declare @definetmp varchar(max)
    set @definetemp =' declare  @tempTable table ( ItemID int, 
                                                  UserID int,
                                                  ....
                     '
    .....
    set @sqlInto = 'Insert into @tempTable' 
    ......
    set @sql = @definetemp +
               @sqlInto + 
               @sqlSelect+
               ....
    
    关键是,您的临时表也在您的动态 sql 中创建。

    【讨论】:

    • 声明@tempTable 或声明#tempTable?这是 SQL Server 还是 Oracle 语法?我是 sql 新手 :)
    • 声明@temptable是表变量,是每个事务,事务结束,它的生命周期结束,是T-SQL; create #temptable 是创建临时表,也是T-SQL;在您的情况下,您还可以创建临时表#temp,但它是每个会话的,请确保在需要时删除或截断。
    • 听起来不错!我需要写一些像 Insert INTO @temp (Col1,Col2,Col3) SELECT Val1,Val2,Val3 这样的东西。正确的?我现在才开始学习 SQL,所以请教你的专业知识:)
    • 在这篇文章之后。 odetocode.com/Articles/365.aspx感谢您的帮助
    • 是的,学习新东西总是好的,记住你的动态 sql 中也需要你的表变量。但是如果你使用临时表#tmp,那就不同了,你可以用你的动态sql直接引用它。无论如何,只需做一点研究。祝你好运。
    猜你喜欢
    • 2012-01-23
    • 1970-01-01
    • 2023-02-09
    • 2011-12-04
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多