我的Dynamic Pivot脚本中的数据类型不兼容

时间:2018-11-01 18:13:07

标签: sql-server tsql pivot

所以我一直在研究动态数据透视脚本,并且几乎可以使用它,但是声明变量存在问题。这是我的代码:

DECLARE @start_date DATE
DECLARE @end_date DATE

SET @start_date = CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-7,'17530101') AS DATE)
SET @end_date = CAST(DATEADD(dd,((DATEDIFF(dd,'17530101',GETDATE())/7)*7)-1,'17530101') AS DATE)

DECLARE @cols  AS NVARCHAR(MAX)='';
DECLARE @query AS NVARCHAR(MAX)='';

SELECT @cols = @cols + QUOTENAME(TicketDate) + ',' 
FROM 
    (SELECT DISTINCT TOP 14 ad.TicketDate 
    FROM AttendDet ad 
    WHERE CAST(ad.TicketDate AS DATE) BETWEEN  @start_date AND @end_date 
        AND ad.EmplCode IS NOT NULL 
    ORDER BY ad.TicketDate) as dates

SELECT @cols = SUBSTRING(@cols, 0, LEN(@cols)) 

SET @query =
'SELECT * FROM
(
    SELECT
        CAST(ad.EmplName AS NVARCHAR(MAX)) AS [EmplName],
        CAST(ad.TicketDate AS DATE) AS [TicketDate],
        ROUND(ad.TotActTime, 2) AS [TotalHrs]
    FROM AttendDet ad
    WHERE ad.EmplCode IS NOT NULL
        AND ad.AttendCode <> 9999
        AND CAST(ad.TicketDate AS DATE) BETWEEN (' + @start_date + ') AND (' + @end_date + ')
) basedata
PIVOT
(
    SUM(TotalHrs) FOR TicketDate IN (' + @cols + ')
) piv'

EXECUTE(@query)

导致错误的行是这一行:

 AND CAST(ad.TicketDate AS DATE) BETWEEN (' + @start_date + ') AND (' + @end_date + ')

我得到的错误是:“数据类型varchar和date在add运算符中不兼容。”我尝试将数据类型更改为VARCHAR,但这没有用,当我这样做时出现以下错误:从字符串转换日期和/或时间时转换失败。

我知道我朝着正确的方向前进,因为如果我手动对该行进行硬编码,例如:

AND CAST(ad.TicketDate AS DATE) BETWEEN ''10/22/18'' AND ''10/28/18''

它可以按预期运行,但是我显然不想这样做,因为它将破坏脚本的全部目的。只要设置了@start_data和@end_date,整个过程就可以正常工作,但是我仍然坚持如何完成此工作。在过去的一个小时里,我一直在尝试各种各样的事情,但无法弄清

预先感谢

3 个答案:

答案 0 :(得分:1)

您需要将其强制转换为varchar,因为SQL此处将+解释为加号或串联。

*

因此您的查询将是这样。注意,我将命令更改为打印而不是执行,因此您可以看到它的外观:

DECLARE @start_date DATE = getdate()
DECLARE @end_date DATE = getdate()
DECLARE @cols varchar(10) = ''
DECLARE @query varchar(max)

SET @query =
'SELECT * FROM
(
    SELECT
        CAST(ad.EmplName AS NVARCHAR(MAX)) AS [EmplName],
        CAST(ad.TicketDate AS DATE) AS [TicketDate],
        ROUND(ad.TotActTime, 2) AS [TotalHrs]
    FROM AttendDet ad
    WHERE ad.EmplCode IS NOT NULL
        AND ad.AttendCode <> 9999
        AND CAST(ad.TicketDate AS DATE) BETWEEN ''' + cast(@start_date as varchar) + ''' AND ''' + cast(@end_date as varchar) + '''
) basedata
PIVOT
(
    SUM(TotalHrs) FOR TicketDate IN (' + @cols + ')
) piv'

print @query

答案 1 :(得分:0)

这应该有效:

    AND CAST(ad.TicketDate AS DATE) BETWEEN (' + CONVERT(varchar(11),@start_date,101) + ') AND (' + CONVERT(varchar(11),@end_date,101) + ')

答案 2 :(得分:0)

您有两种选择。

  1. 使用 :root { --jaune: #FFF701; --bleu: #212D55; } .book{ margin-bottom: 0px; font-size: x-small; color: #364165; text-align: center; } .box { border: 1px solid var(--bleu); background-color: #fff; position: relative; margin-left: 10px; margin-right: 10px; margin-bottom: 16px; } .box::before { content: ' '; border-top: 32px solid #d3d5dd; border-right: 30px solid var(--jaune); width: 0; position: absolute; z-index: 100; } .shadow{ position: absolute; top: 5px; height: 41px; left: 0px; width: 37px; background: #A0A0A0; clip-path: polygon(83% 0%, 4% 63%, 100% 91%); z-index: 1; } .btn_book{ background-color: #212d55; width: 128px; margin-right:79px; margin-left:79px; border: 1px solid #212d55; position: absolute; color: white; text-transform: uppercase; cursor: pointer; } .btn_book:hover{ background-color: var(--jaune); color:#212d55; } .btn_book:hover::before { border-top: 10px solid #212d55; } .btn_book:before { content: ""; height: 0; width: 0; border-top: 10px solid #fffa0a; border-left: 10px solid transparent; border-right: 10px solid transparent; position: absolute; z-index: 1; top:0; left: 0; transform-origin: left; transform: translate(60%) translateY(-71%) rotate(135deg) }运算符来连接字符串,所有值本身都必须是字符串,并且您不能将 <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/> <div class="box" style="width: 18rem; height: 19rem;"> <div class="shadow"></div> <img src="https://b2btolink.com/leboudoir/wp-content/themes/leboudoir/images/logo.png" style="width: 100px; margin-left:80px;"> <p style="text-align:center;color: #212d55;"> <b>NEW CANAAN</b> </p> <hr class="dashed"> <p class="book"> 160 Main Street</p> <p class="book"> New Canaan CT 06840</p> <p class="book"> 203-957-8600</p> <hr class="dashed"> <button type="button" class="btn_book">BOOK NOW</button> </div>隐式转换为字符串,如错误消息所述。不过,您可以将两个日期变量都包装在显式的+中,如果您愿意,可以将DATE包裹起来:

    CAST

  2. 如果您的版本支持(2012+),则只需使用CONCAT。它会帮您完成转换。

    CONVERT