2016-01-21 160 views
-2

动态SP返回值,我使用MS SQL和创建一个动态的存储过程:以相反的顺序

ALTER Procedure [dbo].[sp_MTracking] 
(
@OList varchar(MAX) 
) 
    As 
    BEGIN TRY 
    SET NOCOUNT ON 
    DECLARE @SQL varchar(600) 

    SET @SQL = 'select os.X,os.Y from Table1 as os join Table2 as s on os.sID=s.sID where s.SCode IN ('+ @OList +')' 

    exec (@SQL) 


    END TRY         
    BEGIN CATCH 
     Execute sp_DB_ErrorInfo 
     Select -1 Result 
    END CATCH 

GO 

它工作正常,但我以相反的顺序得到的x,y值。 例如,如果我传递'scode1,scode2'作为参数,我将第2行中的scode1的x,y值和第2行中的x,y值作为scode2。

我怎样才能解决这个问题

感谢

回答

3

这是有点长了评论。

SQL表和结果集表示无序集。没有排序,除非明确使用ORDER BY子句。您的查询没有ORDER BY。因此,你没有理由期望结果以任何特定的顺序。另外,在查询的不同运行中排序可能不同。如果您想按特定顺序显示结果,请添加ORDER BY

也许最简单的方法是使用charindex()

order by charindex(',' + s.code + ',' , ',''' + @olist + ''',') 

这是动态SQL有点更麻烦:

SET @SQL = ' 
select os.X,os.Y 
from Table1 os join 
    Table2 s 
    on os.sID = s.sID 
where s.SCode IN (' + @OList + ') 
order by charindex('','' + s.code + '','', '',''' + @OList + ''', '') 
'; 
+0

你击败了我10秒。如果我只能输入几个字符,我可能会有一个代表推动400k。给你我的赞赏,因为完成我输入的内容会使它看起来该死的近似我现在剽窃你。 – LDMJoe

+0

谢谢Gordon Linoff,我如何根据我的参数列表订购 –

0

没有动态的SQL -

ALTER PROCEDURE [dbo].[sp_MTracking] 
(
    @OList VARCHAR(MAX) 
) 
AS BEGIN 

    SET NOCOUNT ON 

    DECLARE @t TABLE (val VARCHAR(50) PRIMARY KEY WITH(IGNORE_DUP_KEY=ON)) 
    INSERT INTO @t 
    SELECT item = t.c.value('.', 'INT') 
    FROM (
     SELECT txml = CAST('<r>' + REPLACE(@OList, ',', '</r><r>') + '</r>' AS XML) 
    ) r 
    CROSS APPLY txml.nodes('/r') t(c) 

    SELECT os.X, os.Y 
    FROM Table1 os 
    JOIN Table2 s ON os.[sID] = s.[sID] 
    WHERE s.SCode IN (SELECT * FROM @t) 
    --OPTION(RECOMPILE) 

END 
GO 
+2

尽管您的观点有效且重要,但它并不回答提出的原始问题。 –

1

好,这里有几件事。
第一个事情是戈登写的 - 确保结果集的顺序您必须使用order by条款。

第二个,就像Devart在他的回答中演示的那样,你不需要动态sql来处理这类程序。

第三,如果你想按照列表中参数的顺序排列结果,那么你应该使用一个稍微不同的方法,然后Devart写道。
为此,这里是我的2美分:

如果你可以改变存储过程接受VARCHAR(max)一个table valued parameter代替,这将是您最好的选择恕我直言。
如果不是,则必须使用split function从该varchar创建一个表格,然后在选择中使用该表格。
请注意,您将不得不选择一个分割函数,该函数返回一个带有两列的表格 - 一个用于值,另一个用于原始字符串中的位置。

无论如何可以是,该SQL的其余部分应该是这样的:

SELECT os.X, os.Y 
FROM Table1 os 
INNER JOIN Table2 s ON os.[sID] = s.[sID] 
INNER JOIN @TVP t ON s.SCode = t.Value 
ORDER BY t.Sort 

这是假设@TVP是含有一个Value列这是在表2 SCode同一数据类型的表,和一个Sort列(自然是int)。