我已经在MSDN论坛和这里读到了这个,我还不清楚.我认为这是正确的:Varchar(max)将存储为文本数据类型,因此存在缺陷.因此,假设您的字段可靠地低于8000个字符.像我的数据库表中的BusinessName字段.实际上,商业名称可能总是在(从我的帽子里拿出一个数字)500个字符.看起来我运行的大量varchar字段远低于8k字符数.
那么我应该将该字段设为varchar(500)而不是varchar(8000)吗?根据我对SQL的理解,这两者之间没有区别.因此,为了简化生活,我想将所有varchar字段定义为varchar(8000).这有什么缺点吗?
相关:varchar列的大小(我不觉得这个回答了我的问题).
在尝试提高极慢查询的速度时(在两个表上只有几万分钟,在SQL Server 2008上只有几万行,如果重要的话),我将问题缩小到OR我的内连接中,如:
SELECT mt.ID, mt.ParentID, ot.MasterID
FROM dbo.MainTable AS mt
INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID
OR ot.ID = mt.ParentID
Run Code Online (Sandbox Code Playgroud)
我把它更改为(我希望是)一对等效的左连接,如下所示:
SELECT mt.ID, mt.ParentID,
CASE WHEN ot1.MasterID IS NOT NULL THEN
ot1.MasterID ELSE
ot2.MasterID END AS MasterID
FROM dbo.MainTable AS mt
LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID
LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID
WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
..现在查询运行大约一秒钟!
OR加入条件通常是个坏主意吗?或者我在桌子的布局中不知何故不幸?
我正在生成一个脚本,用于自动将更改从多个开发数据库迁移到暂存/生产.基本上,它需要一堆更改脚本,并将它们合并到一个脚本中,将每个脚本包装在一个IF whatever BEGIN ... END语句中.
但是,某些脚本需要一个GO语句,以便例如SQL解析器在创建新列后知道它.
ALTER TABLE dbo.EMPLOYEE
ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
GO -- Necessary, or next line will generate "Unknown column: EMP_IS_ADMIN"
UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
Run Code Online (Sandbox Code Playgroud)
但是,一旦我将其包装在一个IF块中:
IF whatever
BEGIN
ALTER TABLE dbo.EMPLOYEE ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
GO
UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
END
Run Code Online (Sandbox Code Playgroud)
它失败了,因为我发送了一个BEGIN没有匹配的END.但是,如果我删除GO它,它会再次抱怨一个未知的列.
有没有办法在单个IF块中创建和更新同一列?
我有一个Microsoft SQL Server 2008查询,它使用左外连接从三个表返回数据.很多时候,第二个和第三个表中没有数据,所以我得到一个null,我认为这是左外连接的默认值.有没有办法替换select语句中的默认值?我有一个解决方法,我可以选择一个表变量,但感觉有点脏.
SELECT iar.Description, iai.Quantity, iai.Quantity * rpl.RegularPrice as 'Retail',
iar.Compliance FROM InventoryAdjustmentReason iar
LEFT OUTER JOIN InventoryAdjustmentItem iai on (iar.Id = iai.InventoryAdjustmentReasonId)
LEFT OUTER JOIN Item i on (i.Id = iai.ItemId)
LEFT OUTER JOIN ReportPriceLookup rpl on (rpl.SkuNumber = i.SkuNo)
WHERE iar.StoreUse = 'yes'
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我希望Quantity和RegularPrice默认为零.
这是我的简单查询.如果我查询不存在的记录,那么我将不会返回任何内容.我更喜欢在那个场景中返回false(0).寻找简单的方法来解释没有记录.
SELECT CASE
WHEN S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1) THEN 1
ELSE 0
END AS [Value]
FROM Sites S
WHERE S.Id = @SiteId
Run Code Online (Sandbox Code Playgroud) 我试图按周分组记录,将汇总日期存储为一周的第一天.但是,我用于舍入日期的标准技术似乎在几周内没有正常工作(尽管它确实存在了几天,几个月,几年,几个季度以及我应用它的任何其他时间范围).
这是SQL:
select "start_of_week" = dateadd(week, datediff(week, 0, getdate()), 0);
Run Code Online (Sandbox Code Playgroud)
返回2011-08-22 00:00:00.000,这是星期一,而不是星期日.选择@@datefirst返回7,这是星期日的代码,所以据我所知,服务器设置正确.
通过将上面的代码更改为:我可以轻松地绕过这个:
select "start_of_week" = dateadd(week, datediff(week, 0, getdate()), -1);
Run Code Online (Sandbox Code Playgroud)
但事实上,我必须做出这样的例外让我有点不安.此外,如果这是一个重复的问题,请道歉.我发现了一些相关问题,但没有一个专门解决这个问题.
如何使用SQL查询获取MS SQL表的表创建日期?
我在物理上看不到任何表,但我可以查询该特定表.
如何将列值从转换varbinary(max)到varchar人类可读的形式?
我通常有一个"拦截器",它在从/向数据库读取/写入之前进行DateTime转换(从UTC到本地时间,从本地时间到UTC),因此我可以DateTime.Now在整个系统中使用(派生和比较)而不用担心关于时区.
关于计算机之间的序列化和移动数据,没有必要打扰,因为日期时间始终是UTC.
我应该继续以UTC格式存储我的日期(SQL 2008 - datetime)还是应该使用DateTimeOffset(SQL 2008-datetimeoffset)存储它?
数据库中的UTC日期(日期时间类型)已经工作并且已知很长时间了,为什么要更改它?有什么好处?
我已经看过像这样的文章了,但我并不是100%相信.有什么想法吗?
在过去的任何时候,如果有人问我a的最大尺寸varchar(max),我会说2GB,或者查找一个更确切的数字(2 ^ 31-1,或2147483647).
但是,在最近的一些测试中,我发现varchar(max)变量显然超过了这个大小:
create table T (
Val1 varchar(max) not null
)
go
declare @KMsg varchar(max) = REPLICATE('a',1024);
declare @MMsg varchar(max) = REPLICATE(@KMsg,1024);
declare @GMsg varchar(max) = REPLICATE(@MMsg,1024);
declare @GGMMsg varchar(max) = @GMsg + @GMsg + @MMsg;
select LEN(@GGMMsg)
insert into T(Val1) select @GGMMsg
select LEN(Val1) from T
Run Code Online (Sandbox Code Playgroud)
结果:
(no column name)
2148532224
(1 row(s) affected)
Msg 7119, Level 16, State 1, Line 6
Attempting to grow LOB beyond maximum allowed size of …Run Code Online (Sandbox Code Playgroud)