以相反的顺序
动态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。
我怎样才能解决这个问题
感谢
这是有点长了评论。
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 + ''', '')
';
没有动态的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
尽管您的观点有效且重要,但它并不回答提出的原始问题。 –
好,这里有几件事。
第一个事情是戈登写的 - 确保结果集的顺序您必须使用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)。
你击败了我10秒。如果我只能输入几个字符,我可能会有一个代表推动400k。给你我的赞赏,因为完成我输入的内容会使它看起来该死的近似我现在剽窃你。 – LDMJoe
谢谢Gordon Linoff,我如何根据我的参数列表订购 –