storedProcedure参数中的Unicode

时间:2016-06-22 08:51:55

标签: sql-server stored-procedures unicode parameters parameter-passing

我有这个架构名为City的表:

CREATE TABLE [dbo].[City](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [CreatedDate] [datetime] NOT NULL,
    [CreatedBy] [nvarchar](256) NULL,
    [UpdatedDate] [datetime] NOT NULL,
    [UpdatedBy] [nvarchar](256) NULL,
    [SoftDelete] [bit] NOT NULL,
    [LanguageKey] [nvarchar](2) NOT NULL DEFAULT (''),
    [ProvinceName] [nvarchar](50) NULL DEFAULT (''),
    [CityImageId] [bigint] NULL,
    [CityDescription] [nvarchar](500) NOT NULL DEFAULT (''),
    [CityLinkTo] [nvarchar](100) NOT NULL DEFAULT (''),
    [CityCode] [nvarchar](100) NOT NULL DEFAULT (''),
 CONSTRAINT [PK_dbo.City] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[City]  WITH CHECK ADD  CONSTRAINT [FK_dbo.City_dbo.Image_CityImageId] FOREIGN KEY([CityImageId])
REFERENCES [dbo].[Image] ([Id])
GO

ALTER TABLE [dbo].[City] CHECK CONSTRAINT [FK_dbo.City_dbo.Image_CityImageId]
GO

此代码存在一个存储过程:

ALTER Proc [dbo].[InventoryReport]  
(
 @startDate datetime , 
 @endDate datetime ,
 @cityName nvarchar(50)
)
AS
Begin 

Select Id , Name , AllPlace , InventoryPlace , case when Percentage is null then Convert(nvarchar(5),0) else Convert(nvarchar(5) ,Percentage )End AS Percentage
    From (
            Select c.id , c.Name  Name, count(p.id) AllPlace , count(inventoryPlace.InventoryId) InventoryPlace ,
                        ROUND( Convert(float , NULLIF(count(inventoryPlace.InventoryId), 0)  )/ Convert(float,NULLIF(count(p.id), 0)  ),2,null) Percentage
                        from Place  p
                    left join (
                            Select id InventoryId , name  from (
                            Select ROW_NUMBER() Over(Partition by  id , name  Order by  id , date) rn,
                                    * from (
                                    Select  
                                             p.id , p.name , i.date
                                             from Place  p  
                                                left join Room r    on  p.id = r.placeid            and p.SoftDelete = 0    and r.SoftDelete = 0 
                                                join RoomService rs on  r.id = rs.roomid            and rs.SoftDelete = 0 
                                                join inventory  i   on  rs.id = i.roomServiceId     and i.SoftDelete = 0    
                                                                        AND i.date >= @startDate  and i.date <@endDate  and Price <>0 
                                    Group By  p.id , p.name , i.Date 
                                    )a 
                            )r 
                            where r.rn =  DATEDIFF(day , @startDate , @endDate) 
                        )inventoryPlace
                            on p.Id = inventoryPlace.InventoryId
                        right join City c           
                            on  c.id = p.CityId and c.SoftDelete = 0 
                        Where 
                            (@cityName is null OR @cityName = N'' OR c.Name = @cityName) and  p.SoftDelete = 0   and IsVisible = 1
                        Group By c.id , c.name

            ) As PlaceInventoryReport
Order by Id
END

城市表中的名称字段为Nvarchar(50)@cityNamenvarchar(50)。我执行以下代码:

exec InventoryReport @startDate='2016-07-22 00:00:00',@endDate='2016-08-21 00:00:00',@cityName =N'بیرجند'


exec InventoryReport @startDate='2016-07-22 00:00:00',@endDate='2016-08-21 00:00:00',@cityName ='بیرجند' 

第一次执行由Sql Profiler生成并从应用程序调用,然后没有结果(这是错误的),第二次调用由我自己处理并产生一条记录。差异是N'

这两个值'بیرجند'在字符中是相同的,我从地方复制它们。 我无法意识到什么是错的,为什么这两个执行语句的结果不同?

提前致谢。

1 个答案:

答案 0 :(得分:1)

它将字符串声明为 nvarchar 数据类型,而不是 varchar

  1. 您可能已经看过使用传递字符串的Transact-SQL代码 一个N前缀。这表示后续字符串是Unicode (N实际上代表国家语言字符集)。哪一个 表示您传递的是NCHAR,NVARCHAR或NTEXT值 反对CHAR,VARCHAR或TEXT。

    引用Microsoft

  2. 使用字母N前缀Unicode字符串常量。不 N前缀,该字符串被转换为默认代码页 数据库。此默认代码页可能无法识别 字符。