0

私は新年のレポートの作成に取り組んでいます。DBにテーブルの作成権限がないため、このコードを削除して、一時テーブルで機能するようにしました。一時テーブルで必要だとは思わなかったので、PKey部分をコメントアウトしました。

2099年までの日付、BankHolidayの「N」、およびHolidayName一時テーブルの列の「Null」を挿入できます。しかし、「元日」の休日の更新部分を個別に実行したり、1つの長いクエリとして実行したりすると、同じ構文エラーが発生します。「''の近くの構文が正しくありません。」私も自分が何をしているのか知っていると思うとき...

Declare @FirstDate as Date
Declare @LastDate as Date
Declare @WorkingDate as Date

set @FirstDate = '01-01-2010'
SET @LastDate = '12-31-2099'

-- create holiday table replace # with dbo for permanent table
begin
create table #CACFederalReserverHolidays
(
[Date] Date Not Null,
BankHoliday nvarchar(1) Null,
HolidayName nvarchar(50) Null,
) ON [Primary]
end

----add primary key replace # with dbo for permanent table

--begin
--alter table #CACFederalReserverHolidays add constraint
--PK_CACFederalReserverHolidays Primary Key Clustered
--(
--Date
--)
--With (Statistics_NoRecompute = off,
--  Ignore_Dup_Key = Off,
--  Allow_Row_Locks = On,
--  Allow_Page_Locks = On) On [Primary]
--end

-- insert the first date

Insert into #CACFederalReserverHolidays 
([Date],[BankHoliday])
Values
(@FirstDate,'N')

-- insert the remaining dates by adding 1 to the last date
While (select MAX(DATE)
from #CACFederalReserverHolidays
) < @LastDate

begin
Set @WorkingDate =  DATEADD (day,1,(select MAX(DATE) from #CACFederalReserverHolidays))
if @WorkingDate <= @LastDate
    begin
        insert into #CACFederalReserverHolidays
        ([Date], [BankHoliday])
        Values
        (@WorkingDate, 'N')
            end
    else
        break
end

--ID Fed Holidays
begin
update #CACFederalReserverHolidays
 set BankHoliday = 'Y', 
    HolidayName = 'New Year''s Day'
    where DATEPART(day,Date) = 1
    and DATEPART(month,Date) = 1
    and DATEPART(Dw,Date) between 2 and 6
    
update #CACFederalReserverHolidays
     set BankHoliday = 'Y', 
    HolidayName = 'New Year''s Day'
    where DATEPART(day,Date) = 1
    and DATEPART(month,Date) = 1
    and DATEPART(Dw,Date) = 2
end

begin 
-- MLK Day, 3rd Mon in January
update #CACFederalReserverHolidays
 set BankHoliday = 'Y', 
    HolidayName = 'Martin Luther King Day'
    where DATEPART(day,Date) between 15 and 21
    and DATEPART(month,Date) = 1
    and DATEPART(Dw,Date) = 2
end     
4

2 に答える 2

2

SQL Server(またはManagement Studio)で実際のバグを見つけた可能性があると思います。

これらの2つのUPDATEステートメント:

update #CACFederalReserverHolidays
 set BankHoliday = 'Y', 
    HolidayName = 'New Year''s Day'
    where DATEPART(day,Date) = 1
    and DATEPART(month,Date) = 1
    and DATEPART(Dw,Date) between 2 and 6
    
update #CACFederalReserverHolidays
     set BankHoliday = 'Y', 
    HolidayName = 'New Year''s Day'
    where DATEPART(day,Date) = 1
    and DATEPART(month,Date) = 1
    and DATEPART(Dw,Date) = 2

最初の2行に、ある種の無効なスペース文字や改行があるように見えます。ただし、一度に1文字ずつスキャンすると、これを引き起こすUnicode値が見つかりません。それでも、すべてのスペースと改行を編集してから手動で再入力すると、クエリで「無効な構文」エラーが発生しなくなりました。

同じことをすることをお勧めします。ただし、最初に、これらの行をコピーしてMicrosoft Connectに移動し、バグの可能性があるものとして入力してください。

(実際、必要に応じて、これをMS Connectに入力できます。)


これをSQLServerのバグとしてMicrosoftConnectに入力しました:https ://connect.microsoft.com/SQLServer/feedback/details/775641/ssms-throws-spurious-incorrect-syntax-error 。気軽にそこに行って、賛成またはコメントしたり、自分で複製できるかどうかを示したりしてください。


私はそれを理解しました。これがConnectの私の改訂された投稿であり、それはそれをかなりよく説明しています:

SSMSで次のテキストを逐語的に実行すると:

update #CACFederalReserverHolidays
 set BankHoliday = 0

「''の近くの構文が正しくありません」というエラーがスローされます。私が知る限り、#tempテーブルは未定義であると言うべきです。注:#tempテーブルが定義されている場合でも、同じエラーがスローされます。

これは、サポートフォーラム(ここ: 一時テーブルの更新)でのユーザーの質問から得ました。ユーザーのテキストを切り取ってSSMSに貼り付けると、この2行に絞り込むことができました。多くの編集とテストを行った結果、1行目と2行目の間の改行とスペースを削除してから、自分で再入力した場合にのみ問題が解決することがわかりました。目に見えない/無効な文字を疑って、テキストを引用し、次のように文字ごとに調べました。

select unicode(substring('update #CACFederalReserverHolidays
 set BankHolidayX = 0', 35,1))

しかし、文字35、36、および37を見ると、Unicode値13、10、および63(CR、LF、およびスペース)のみが明らかになりました。

私の知る限り、これはManagementStudioまたはSQLServerパーサー自体のバグである必要があります。

これまでSQLServer2012でこれを再現しただけですが、元のユーザーがSQLServer2008から報告したことに注意してください。


OK、Unicode値を調べる前にASCIIに変換していたため、上記の検査手順に欠陥があることに気づきました。正しい式を使用する場合:

select unicode(substring(N'update #CACFederalReserverHolidays
 set BankHolidayX = 0', 37,1))

文字37が実際にはUnicode値8200であることがわかります。私はこれに慣れていませんが、無効であると思います。


簡単に言うと、SQLコードの一部のスペース(具体的には、set ..後の行の前のスペースupdate..は真のスペースではなく(Unicode 63)ですが、実際にはUnicode文字8200( "PUNCTUATION SPACE"、U + 2008)。明らかに、これらをスペースに置き換える必要があります。

于 2013-01-02T22:09:05.580 に答える
0

アフターは何のbeginために--ID Fed Holidays

それらはそこでは意味がありません。whileこれらは、ループの開始と終了にのみ意味があります。

それがあなたの問題の原因であるならIDK、しかしそれは私が最初に気づいたことです

于 2013-01-02T21:51:22.483 に答える