where 子句中包含列名的存储过程

Stored Procedure with Column name in where clause

我有一个 table 和三个 columns.I 想创建一个存储过程,其中包含三个参数 @Month、@Year 和 @column_Name,结果输出为 below.I想要对 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

但它 returns 一个错误:

Msg 241, Level 16, State 1, Procedure Test_SP, Line 8
Conversion failed when converting date and/or time from character string.

请帮忙

不要乱用字符串函数来获取时间部分。这是最糟糕的方法。相反,让 Sql 服务器将其转换为 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