我使用的是SQL Server 2012.我有一个名为“Table1”的示例表,其中有七列。
CREATE TABLE TABLE1
(
Field1 INT ,
Field2 INT ,
Field3 INT ,
Field4 INT ,
Field5 INT ,
Field6 INT ,
Field7 INT
)
GO
INSERT INTO TABLE1 VALUES (1,2,9,5,1,5,85)
INSERT INTO TABLE1 VALUES (2,6,8,4,1,4,45)
INSERT INTO TABLE1 VALUES (3,5,7,3,5,6,1)
INSERT INTO TABLE1 VALUES (4,4,6,1,51,4,1)
INSERT INTO TABLE1 VALUES (5,5,5,4,7,2,7)
INSERT INTO TABLE1 VALUES (6,5,4,6,4,7,8)
INSERT INTO TABLE1 VALUES (7,12,5,3,2,5,3)
INSERT INTO TABLE1 VALUES (8,1,6,5,9,5,1)
INSERT INTO TABLE1 VALUES (9,1,13,2,1,7,3)
INSERT INTO TABLE1 VALUES (10,6,9,3,6,2,6)
INSERT INTO TABLE1 VALUES (11,2,1,2,8,7,7)
INSERT INTO TABLE1 VALUES (12,7,6,1,3,3,2)
INSERT INTO TABLE1 VALUES (13,7,2,6,4,7,1)
GO
我创建了以下存储过程,此SP能够按列查询所请求的订单来查询数据。 我可以通过(ASC或Desc)查询我的表中每个单列和顺序的可能性。
CREATE Procedure ProceName
(
@OrderByField INT = 1,
@OrderDirection INT = 0 -- 0 = Asc , 1 = Desc
)
As
Begin
SELECT
*
FROM Table1
ORDER BY
CASE WHEN @OrderDirection=0 AND @OrderByField=1 THEN Field1 END ASC,
CASE WHEN @OrderDirection=0 AND @OrderByField=2 THEN Field2 END ASC,
CASE WHEN @OrderDirection=0 AND @OrderByField=3 THEN Field3 END ASC,
CASE WHEN @OrderDirection=0 AND @OrderByField=4 THEN Field4 END ASC,
CASE WHEN @OrderDirection=0 AND @OrderByField=5 THEN Field5 END ASC,
CASE WHEN @OrderDirection=0 AND @OrderByField=6 THEN Field6 END ASC,
CASE WHEN @OrderDirection=0 AND @OrderByField=7 THEN Field7 END ASC,
CASE WHEN @OrderDirection=1 AND @OrderByField=1 THEN Field1 END DESC,
CASE WHEN @OrderDirection=1 AND @OrderByField=2 THEN Field2 END DESC,
CASE WHEN @OrderDirection=1 AND @OrderByField=3 THEN Field3 END DESC,
CASE WHEN @OrderDirection=1 AND @OrderByField=4 THEN Field4 END DESC,
CASE WHEN @OrderDirection=1 AND @OrderByField=5 THEN Field5 END DESC,
CASE WHEN @OrderDirection=1 AND @OrderByField=6 THEN Field6 END DESC,
CASE WHEN @OrderDirection=1 AND @OrderByField=7 THEN Field7 END DESC End
GO
EXECUTE ProceName @OrderByField=1, @OrderDirection=0
EXECUTE ProceName @OrderByField=6, @OrderDirection=1
现在我需要更改此sp以按系列列的顺序接受多列。它们可以按名称或按列顺序传递。 在这种情况下,我应该能够像下面的命令一样执行我的SP:
EXECUTE ProceName @OrderByField='6,7,2', @OrderDirection='0,1,1'
如何在不使用sp_executesql(动态查询)的情况下实现此gool ?
答案 0 :(得分:0)
嗯,除非你试图为每一列选择asc和desc,否则你的上升和下降在你的情况下并不重要。这是使用最后一列。
DECLARE @OrderByField VARCHAR(64) = '1,3,7'
DECLARE @DynamicColumns VARCHAR(256) = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@OrderByField,1,'FIELD1'),2,'FIELD2'),3,'FIELD3'),4,'FIELD4'),5,'FIELD5'),6,'FIELD6'),7,'FIELD7')
DECLARE @OrderDirection INT = 1
DECLARE @order varchar(4)
SET @order = CASE WHEN @OrderDirection = 1 THEN 'DESC' ELSE 'ASC' END
--uncomment this line of code to add the sort to every column which only matters for DESC since ASC is default
--SET @DynamicColumns = REPLACE(@DynamicColumns,',', ' ' + @order + ',')
DECLARE @sql VARCHAR(MAX) = (
'SELECT
*
FROM Table1
ORDER BY ' + @DynamicColumns + ' ' + @order)
SELECT @sql
EXEC(@sql)
答案 1 :(得分:0)
CREATE Procedure ProceName
(
@OrderByField VARCHAR(100),
@OrderDirection VARCHAR(100),
)
As
Begin
Declare @SQL VARCHAR(MAX)
if OBJECT_ID('Example1') is not null
begin
drop table Example
end
if OBJECT_ID('Example2') is not null
begin
drop table Example2
end
Create table Example1
(
id int identity(1,1),
Field varchar(20)
)
Create table Example2
(
id int identity(1,1),
OrderNumber varchar(10)
)
--iterate each element for both @OrderByField and @OrderDirection
Declare @separator char(1)=','
Declare @position int = 0
Declare @name varchar(20)
Set @OrderByField = @OrderByField + @separator
---------------------------------------------------------------------------
/*iterate each for @OrderByField */
---------------------------------------------------------------------------
While CHARINDEX (@separator,@OrderByField,@position) != 0
BEGIN
SET @name = SUBSTRING (@OrderByField,@position,CHARINDEX (@separator,@OrderByField,@position)-@position)
SET @SQL = 'Insert into Example1([Field]) Values(' + char(39) + @name + char(39) + ')'
EXEC(@SQL)
SET @position = CHARINDEX(@separator,@OrderByField,@position)+1
END
---------------------------------------------------------------------------
/*iterate each for @OrderDirection */
---------------------------------------------------------------------------
SET @position = 0 --do not forget to reset the position number
Set @OrderDirection = @OrderDirection + @separator
While CHARINDEX (@separator,@OrderDirection,@position) != 0
BEGIN
SET @name = SUBSTRING (@OrderDirection,@position,CHARINDEX (@separator,@OrderDirection,@position)-@position)
SET @SQL = 'Insert into Example2([OrderNumber]) Values(' + char(39) + @name + char(39)+ ')'
EXEC(@SQL)
SET @position = CHARINDEX(@separator,@OrderDirection,@position)+1
END
Set @name = '' --reset the @name for the use of Cursor
declare @NewName varchar(500) =''
Declare row_cursor CURSOR
FOR
select 'Field'+a.Field + ' '+ case when b.OrderNumber = 0 then 'ASC' else 'DESC' end +',' as command
from Example1 as a
inner join Example2 as b
on b.id = a.id
OPEN row_cursor
FETCH NEXT FROM row_cursor into @name
WHILE (@@FETCH_STATUS =0)
begin
Set @NewName = @NewName + @name
FETCH NEXT FROM row_cursor into @name
end
close row_cursor
deallocate row_cursor
SET @NewName = REVERSE(STUFF(REVERSE(@NewName),1,1,''))
SET @SQL = 'Select * From Table1 Order by ' + @NewName
--Print(@SQL)
EXEC (@SQL)
END