在where子句中使用列名称存储过程

时间:2015-01-08 18:18:19

标签: sql-server

我有一个有三列的表。我想用@ Month,@ Year和@column_Name这三个参数创建存储过程,结果如下所示。我想对column1和column2中存在的值求和,即数据是以HH形式出现:mm:ss格式为字符串应该导致分钟[例如。 ' 01:00:00'结果为60],其中参数在where子句中。

注意:Column1Column2的数据类型为varchar,数据格式为hh:mm:ss

表格中的样本日期

Date_Col                     Column1        Column2

2014-12-17 10:00:00.000      01:10:00       00:15:00
2014-12-18 11:12:00.000      02:22:00       00:52:00
2015-01-15 09:32:00.000      00:34:00       01:09:00
2015-01-16 11:43:00.000      10:00:00       02:00:00

存储过程的结果

@Month = 12 ,@Year = 2014,@Column_Name = Column1

然后

Date_Col                             Column1
--------------------------------------------------------------------    
2014-12-17                           70   [01:10:00 = 60 + 10 min]
2014-12-18                           142

以下是我所指的SP



ALTER PROCEDURE [dbo].[Test_SP] 
@Column_Name varchar(50)
AS
BEGIN
    SET NOCOUNT ON;

    SELECT
        CAST(CONVERT(DATE, date_col) AS Varchar(50)) AS 'Date',
        DATEPART(HOUR, CAST(@Column_Name AS varchar(50))) * 60 +
            DATEPART(mi, CAST (CAST(@Column_Name AS varchar(50)) AS varchar)) as Column_Name
    FROM 
        Test_Table 
    WHERE
        @Column_Name IN (SELECT COLUMN_NAME 
                         FROM [TEST].INFORMATION_SCHEMA.COLUMNS 
                         WHERE TABLE_NAME = N'Test_Table') 
END




但它返回错误:

  

Msg 241,Level 16,State 1,Procedure Test_SP,Line 8
  从字符串转换日期和/或时间时转换失败。

请帮助

1 个答案:

答案 0 :(得分:0)

不要乱用字符串函数来获取时间部分。这是最糟糕的做法。相反,让Sql Server将其转换为Time类型并使用日期和时间函数。这段代码中的两个SELECT都为我生成70

declare @test varchar(8); set @test = '01:10:00'

declare @t1 time;set @t1 = CAST(@test as time);
declare @t2 time;set @t2 = '00:00:00';

select DATEDIFF(minute, @t2, @t1)
select DATEPART(hour, @t1) * 60 + DATEPART(minute, @t1)

在那里有一个隐式转换,它将@test值转换为DATEPART()函数的兼容类型。这样可以更好地更多获取您的分钟值,如果您首先使用TIME类型存储数据,情况会更好。

对于列名部分,您应该使用CASE语句。完整代码如下所示:

SELECT Date_Col, 
    DATEDIFF(minute, '00:00:00',
       CASE @ColumnName WHEN 'Column1' THEN Column1
                        WHEN 'Column2' THEN Column2
                        ELSE NULL END) As Minutes
FROM Test_Table
WHERE YEAR(Date_Col) = @Year AND MONT(Date_Col) = @Month