【发布时间】:2016-10-24 02:25:32
【问题描述】:
我有一个名为 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),@cityName 为nvarchar(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'
这两个值“بیرجند”在字符上是相同的,我已经从原处复制了它们。 我不知道出了什么问题,为什么这两个执行语句的结果不同?
提前致谢。
【问题讨论】:
-
N-prefix 告诉 sql server 将字符串视为 unicode 值。而如果不提及相同的内容,它将被视为字符串。更多信息在这里:support.microsoft.com/en-us/kb/239530跨度>
-
@Malcolm 当我们将列的数据类型定义为 NVARCHAR 时,它会将值存储为 UNICODE 格式还是字符串?如果它存储为字符串,那么为什么我们不应该使用 8000 字符长度的 varchar?如果它以 UICODE 格式存储,为什么值不匹配?
-
@samira 您是否对列的语言使用了准确的排序规则..?
-
@RajeshRanjan 是的,我使用了排序,但它也不起作用。
-
@samira 你能分享一下表格脚本和一些示例记录吗?
标签: sql-server stored-procedures unicode parameters parameter-passing