大多数开发人员都不知道的SQL Server功能/命令

时间:2009-08-06 15:05:19

标签: sql sql-server

  

可能重复:
  Hidden Features of SQL Server

我已经作为.NET开发人员工作了一段时间,但现在主要针对SQL Server数据库3年多了。我觉得从开发的角度来看,我对SQL Server的掌握相当不错,但我很惭愧地承认我今天刚刚从这个答案中学到了“WITH TIES” - Top 5 with most friends

在SO上看到这样的问题和答案是令人羞愧的,因为它让我意识到我真的不知道我认为我做的多少,并帮助重新激发我的意志,以便了解更多,所以我想到了什么更好而不是要求专家群众输入其他方便的命令/功能。

普通开发人员可能没有意识到的最有用的功能/命令是什么?

顺便说一句 - 如果你像我一样,并且不知道“WITH TIES”的用途,这里有一个很好的解释。你会很快看到为什么我感到惭愧我不知道它。我可以看到它在哪里有用。 - http://harriyott.com/2007/06/with-ties-sql-server-tip.aspx

我意识到这是一个主观问题所以请在关闭之前至少留出几个答案。 :)我会尝试编辑我的问题以跟上您的回复列表。感谢

[编辑] - 以下是回复摘要请向下滚动以获取更多信息。再次感谢guys / gals。

  • MERGE - 从行源INSERT / UPDATE / DELETE到表中的单个命令。
  • SQL Server 2008的FILESTREAM功能允许使用SQL Server 2008和NTFS文件系统的组合存储和有效访问BLOB数据
  • CAST - 获取没有时间部分的日期
  • Group By - 我得说你肯定应该知道这个
  • SQL Server Management Studio
  • 交易
  • 在嵌套过程调用之间共享本地范围临时表
  • INSERT INTO
  • MSDN
  • JOINS
  • PIVOT和UNPIVOT
  • WITH(FORCESEEK) - 强制查询优化器仅使用索引查找操作作为表中数据的访问路径。
  • FOR XML
  • COALESCE
  • 如何缩小数据库和日志文件
  • INFORMATION_SCHEMA
  • 在Management Studio 2005中设置IMPLICIT_TRANSACTIONS
  • 派生表和公用表表达式(CTE)
  • OUTPUT子句 - 允许访问名为inserted and deleted(如触发器)的“虚拟”表
  • CTRL + 0以插入null
  • SQL Server 2008中的空间数据

21 个答案:

答案 0 :(得分:11)

FileStream in SQL Server 2008:SQL Server 2008的FILESTREAM功能允许使用SQL Server 2008和NTFS文件系统的组合来存储和有效访问BLOB数据。

创建用于存储FILESTREAM数据的表

数据库具有FILESTREAM文件组后,可以创建包含FILESTREAM列的表。如前所述,FILESTREAM列定义为具有FILESTREAM属性的varbinary(max)列。以下代码创建一个包含单个FILESTREAM列的表

USE Production;
GO
CREATE TABLE DocumentStore (
       DocumentID INT IDENTITY PRIMARY KEY,
       Document VARBINARY (MAX) FILESTREAM NULL,
       DocGUID UNIQUEIDENTIFIER NOT NULL ROWGUIDCOL
              UNIQUE DEFAULT NEWID ())
FILESTREAM_ON FileStreamGroup1;
GO

答案 1 :(得分:9)

  • SQL Server 2008(以及Oracle 10g)中:MERGE

    从行源INSERT / UPDATE / DELETE1的单个命令。

  • 要生成从31WITH cal AS ( SELECT 1 AS day UNION ALL SELECT day + 1 FROM cal WHERE day <= 30 ) 的数字列表(例如,对于日历):

    DESC
  • 群集表中带有column DESC, cluster_key ASC子句的单列索引可用于CREATE INDEX ix_column_desc ON mytable (column DESC) SELECT TOP 10 * FROM mytable ORDER BY column DESC, pk -- Uses the index SELECT TOP 10 * FROM mytable ORDER BY column, pk -- Doesn't use the index 上的排序:

    CROSS APPLY
  • OUTER APPLYSELECT * FROM mytable CROSS APPLY my_tvf(mytable.column1) tvf SELECT * FROM mytable CROSS APPLY ( SELECT TOP 5 * FROM othertable WHERE othertable.column2 = mytable.column1 ) q :允许连接取决于要连接的表值的行源:

    EXCEPT
  • INTERSECTNULL运营商:允许选择包含DECLARE @var1 INT DECLARE @var2 INT DECLARE @var3 INT SET @var1 = 1 SET @var2 = NULL SET @var2 = NULL SELECT col1, col2, col3 FROM mytable INTERSECT SELECT @val1, @val2, @val3 -- selects rows with `col1 = 1`, `col2 IS NULL` and `col3 IS NULL` SELECT col1, col2, col3 FROM mytable EXCEPT SELECT @val1, @val2, @val3 -- selects all other rows s的条件

    WITH ROLLUP
  • SELECT month, SUM(sale) FROM mytable GROUP BY month WITH ROLLUP Month SUM(sale) --- --- Jan 10,000 Feb 20,000 Mar 30,000 NULL 60,000 -- a total due to `WITH ROLLUP` 子句:为所有分组行选择总计

    {{1}}

答案 2 :(得分:6)

许多SQL Server开发人员似乎仍然不了解DELETE,INSERT和UPDATE语句中的 OUTPUT clause (SQL Server 2005及更新版本)。

知道哪些行已被INSERTed,UPDATEd或DELETEd非常有用,并且OUTPUT子句允许非常容易地执行此操作 - 它允许访问名为inserted和{{的“虚拟”表。 1}}(如在触发器中):

deleted

如果要将值插入具有INT IDENTITY主键字段的表,并使用OUTPUT子句,则可以立即获取插入的新ID:

DELETE FROM (table)
OUTPUT deleted.ID, deleted.Description
WHERE (condition)

如果你正在更新,知道改变了什么是非常有用的 - 在这种情况下,INSERT INTO MyTable(Field1, Field2) OUTPUT inserted.ID VALUES (Value1, Value2) 表示新值(在UPDATE之后),而inserted指的是旧值在更新之前:

deleted

如果返回大量信息,OUTPUT的输出也可以重定向到临时表或表变量(UPDATE (table) SET field1 = value1, field2 = value2 OUTPUT inserted.ID, deleted.field1, inserted.field1 WHERE (condition) )。

非常有用 - 而且知之甚少!

马克

答案 3 :(得分:6)

COALESCE(),它接受字段和要使用的值,如果字段为空。 例如,如果你有一个包含city,State,Zipcode的表,你可以使用COALESCE()将地址作为单个字符串返回,IE:

城市|国家|邮政编码

休斯顿|德克萨斯州77058

博蒙特|德克萨斯州NULL

NULL |俄亥俄州| NULL

如果您要对表运行此查询:

select city + ‘  ‘ + COALESCE(State,’’)+ ‘  ‘+COALESCE(Zipcode, ‘’)

会回来:

Houston Texas 77058

Beaumont Texas

俄亥俄

您还可以使用它来转移数据,IE:

DECLARE @addresses VARCHAR(MAX)
SELECT @addresses = select city + ‘  ‘ + COALESCE(State,’’)+ ‘  ‘
+COALESCE(Zipcode, ‘’)             + ‘,’ FROM tb_addresses
SELECT @addresses 

会回来: Houston Texas 77058,Beaumont Texas,Ohio

答案 4 :(得分:6)

在过程中创建#TempTable后,它在所有存储过程中都可用,然后从原始过程调用它们。这是在程序之间共享集合数据的好方法。见:http://www.sommarskog.se/share_data.html

答案 5 :(得分:6)

令人惊讶的是,有多少人在不受SQL Server保护的情况下工作,因为他们不了解交易!

BEGIN TRAN
...
COMMIT / ROLLBACK

答案 6 :(得分:6)

有一些方法可以获得没有时间部分的约会;这是一个非常高效的人:

SELECT CAST(FLOOR(CAST(getdate() AS FLOAT))AS DATETIME) 

确实对于SQL Server 2008:

SELECT CAST(getdate() AS DATE) AS TodaysDate

答案 7 :(得分:4)

"Information_Schema"为我提供了很多视图,可用于收集有关SQL对象表,过程,视图等的信息。

答案 8 :(得分:4)

如果您使用的是Management Studio 2005,则可以将其作为事务自动执行查询。在新的查询窗口中,转到Query-&gt; Query Options。然后单击ANSI“选项卡”(左侧)。检查SET IMPLICIT_TRANSACTIONS。单击确定。现在,如果您在当前查询窗口中运行任何查询,它将作为事务运行,您必须在继续之前手动ROLLBACK或COMMIT。此外,这仅适用于当前查询窗口;预先存在/新查询窗口需要设置选项。

我个人发现它很有用。然而,这不适合胆小的人。您必须记住ROLLBACK或COMMIT您的查询。如果您切换到不同的查询窗口(甚至是新的查询窗口),它将 NOT 告诉您有待处理的事务。但是,它会告诉您是否尝试关闭查询窗口。

答案 9 :(得分:3)

答案 10 :(得分:3)

答案 11 :(得分:3)

BACKUP LOG <DB_NAME> WITH TRUNCATE_ONLY

DBCC_SHRINKDATABASE(<DB_LOG_NAME>, <DESIRED_SIZE>)

当我开始在MS SQL Server上管理非常大的数据库并且日志文件超过300 GB时,这些语句挽救了我的生命。在大多数情况下,收缩数据库将不起作用。

在运行它们之前,一定要对LOG进行完整备份,然后运行它们以完成DB的完整备份(恢复序列不再有效)。

答案 12 :(得分:3)

大多数SQL Server开发人员应该了解并使用派生表和公用表表达式(CTE)。

答案 13 :(得分:2)

文档

说来可悲,但我得出的结论是,最隐蔽的特点,开发人员不知道的是在MSDN上的文档。以RESTORE之类的Transact-SQL动词为例。 BOL不仅涵盖RESTORE的syntaxarguments。但在文档方面,这只是冰山一角。 BOL涵盖:

列表一直在继续,这只是一个主题(备份和恢复)。 SQL Server的每个功能都具有类似的覆盖范围。估计不是所有东西都会得到详细的备份和恢复,但所有内容都有记录,并且每个功能都有How To主题。

可用的信息量非常荒谬。然而,文档是最少使用的资源之一,因此我投票支持它是隐藏功能。

答案 14 :(得分:2)

物化视图怎么样?将聚簇索引添加到视图,您可以有效地创建包含自动更新的重复数据的表。减慢插入和更新,因为您正在执行两次操作,但您可以更快地选择特定子集。显然,数据库优化器使用它而无需您明确地调用它。

Is a view faster than a simple query?

答案 15 :(得分:1)

这听起来很愚蠢,但我看了很多疑问,我只是问自己这个人不知道GROUP BY是什么?我不确定大多数开发人员是否都没有意识到这一点,但有时我想知道它。

答案 16 :(得分:1)

Spacial Data in SQL Server 2008,即将Lat / Long数据存储在地理数据类型中,并能够使用随附的函数进行计算/查询。

它支持Planar和Geodetic数据。

答案 17 :(得分:1)

当我第一次开始作为程序员工作时,我开始使用SQL Server 2000.我曾在Oracle和MySQL上学过DB理论,因此我对SQL Server 2000知之甚少。

但是,事实证明我加入的开发人员也没有,因为他们不知道你可以将datetime(和相关的)数据类型转换为带有内置函数的格式化字符串。他们使用的是他们开发的非常低效的自定义功能。我很高兴向他们展示他们的方式的错误......(我不再和那家公司在一起...... :-D)

使用该注释:

所以我想把它添加到列表中:

 select Convert(varchar, getdate(), 101) -- 08/06/2009
 select Convert(varchar, getdate(), 110) -- 08-06-2009

这是我经常使用的两个。还有更多:CAST and CONVERT on MSDN

答案 18 :(得分:1)

WITH (FORCESEEK)强制查询优化器仅使用索引查找操作作为表中数据的访问路径。

答案 19 :(得分:1)

为什么我想说JOINS?

派生表是我的最爱之一。它们的表现比相关的子查询好得多,但人们可能会继续使用相关的子查询。

派生表的示例:

select f.FailureFieldName, f.RejectedValue, f.RejectionDate,
         ft.FailureDescription, f.DataTableLocation, f.RecordIdentifierFieldName,
         f.RecordIdentifier , fs.StatusDescription 
    from dataFailures f
    join(select max (dataFlowinstanceid) as dataFlowinstanceid 
            from dataFailures 
            where dataflowid = 13)a 
    on f.dataFlowinstanceid = a.dataFlowinstanceid
    join FailureType ft on f.FailureTypeID = ft.FailureTypeID
    join FailureStatus fs on f.FailureStatusID = fs.FailureStatusID

答案 20 :(得分:1)

使用ctrl-0在单元格中插入空值