我正在使用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'作为参数,我得到第二行中scode1的x,y值和scode2作为第一行的x,y值。
如何解决此问题
由于
答案 0 :(得分: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 + ''', '')
';
答案 1 :(得分:1)
嗯,这里有几件事
第一个是Gordon写的东西 - 为了确保结果集的顺序,你必须使用order by
子句。
第二次,就像Devart在他的回答中所表明的那样,你不需要动态的sql来完成这种程序。
第三次,如果您希望按照列表中参数的顺序排序结果,则应使用稍微不同的方法,然后Devart写道。
因此,这是我的2美分:
如果您可以更改存储过程以接受table valued parameter而不是VARCHAR(max)
,这将是您最好的选择恕我直言。
如果没有,则必须使用split function从varchar
创建一个表,然后在您的选择中使用该表。
请注意,您必须选择一个split函数,该函数返回一个包含两列的表 - 一个用于值,另一个用于它在原始字符串中的位置。
无论情况如何,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,自然而然。)
答案 2 :(得分:0)
没有动态sql -
null