SQL Serverの隠された機能


215

SQL Serverの隠された機能は何ですか?

たとえば、文書化されていないシステムストアドプロシージャ、非常に役立つが十分に文書化されていないことを行うためのトリック?


答え

すばらしい回答をありがとうございました。

ストアドプロシージャ

  • sp_msforeachtable: '?'を使用してコマンドを実行します 各テーブル名に置き換えられます(v6.5以降)
  • sp_msforeachdb:「?」を使用してコマンドを実行します 各データベース名に置き換えられます(v7以上)
  • sp_who2: sp_whoと同じですが、ブロックのトラブルシューティングに関するより多くの情報が含まれます(v7以降)
  • sp_helptext:ストアドプロシージャのコードが必要な場合は、ビューとUDF
  • sp_tables:スコープ内のデータベースのすべてのテーブルとビューのリストを返します。
  • sp_stored_procedures:すべてのストアドプロシージャのリストを返す
  • xp_sscanf:文字列から、各フォーマット引数で指定された引数の場所にデータを読み取ります。
  • xp_fixeddrives::最大の空き容量がある固定ドライブを検索します
  • sp_help:テーブルの構造、インデックス、テーブルの制約を知りたい場合。ビューとUDF。ショートカットはAlt + F1です

切れ端

  • ランダムな順序で行を返す
  • 最終更新日別のすべてのデータベースユーザーオブジェクト
  • 返却日のみ
  • 現在の週のどこかに日付があるレコードを検索します。
  • 先週発生した日付のレコードを検索します。
  • 現在の週の初めの日付を返します。
  • 先週の初めの日付を返します。
  • サーバーにデプロイされた手順のテキストを参照してください
  • データベースへのすべての接続をドロップします
  • テーブルチェックサム
  • 行チェックサム
  • データベース内のすべてのプロシージャを削除します
  • 復元後にログインIDを正しく再マッピングする
  • INSERTステートメントからのストアドプロシージャの呼び出し
  • キーワードによる手順の検索
  • データベース内のすべてのプロシージャを削除します
  • プログラムでデータベースのトランザクションログをクエリします。

関数

  • HashBytes()
  • EncryptByKey
  • PIVOTコマンド

その他

  • 接続文字列エクストラ
  • TableDiff.exe
  • ログオンイベントのトリガー(Service Pack 2の新機能)
  • 永続的な計算列(pcc)でパフォーマンスを向上させます。
  • sys.database_principlesのDEFAULT_SCHEMA設定
  • 強制パラメーター化
  • Vardecimalストレージ形式
  • 最も人気のあるクエリを数秒で把握
  • スケーラブルな共有データベース
  • SQL Management Studioのテーブル/ストアドプロシージャフィルター機能
  • トレースフラグ
  • GOバッチを繰り返した後の数
  • スキーマを使用したセキュリティ
  • 組み込みの暗号化関数、ビュー、トリガー付きのベーステーブルを使用した暗号化

4
わかっている場合は、各回答に適切なバージョンを含めると便利です。(2000以降、2005年、2000年のみなど)
bw

この質問には多くの利点があります。削除しないでください!:-)
Sklivvz

回答:


91

Management Studioでは、GOのバッチ終了マーカーの後に番号を付けて、その回数だけバッチを繰り返すことができます。

PRINT 'X'
GO 10

「X」を10回印刷します。これにより、繰り返し作業を行うときに、面倒なコピー/貼り付けを行う必要がなくなります。


70

多くのSQL Server開発者は、DELETE、INSERT、およびUPDATEステートメントのOUTPUT句(SQL Server 2005以降)についてまだ知らないようです。

どの行がINSERT、UPDATE、またはDELETEされたかを知ることは非常に役立ちます。OUTPUT句を使用すると、これを非常に簡単に行うことができます。これにより、呼び出さinsertedれたdeleted(トリガーのような)「仮想」テーブルにアクセスできます。

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

INT IDENTITY主キーフィールドを持つテーブルに値を挿入する場合、OUTPUT句を使用すると、挿入された新しいIDをすぐに取得できます。

INSERT INTO MyTable(Field1, Field2)
OUTPUT inserted.ID
VALUES (Value1, Value2)

また、更新する場合、何が変更されたかを知ることは非常に役立ちます。この場合、inserted(UPDATE後の)新しい値を表しdeleted、UPDATEの前の古い値を参照します。

UPDATE (table)
SET field1 = value1, field2 = value2
OUTPUT inserted.ID, deleted.field1, inserted.field1
WHERE (condition)

大量の情報が返される場合は、OUTPUTの出力を一時テーブルまたはテーブル変数(OUTPUT INTO @myInfoTable)にリダイレクトすることもできます。

非常に便利-あまり知られていません!

マーク


52

sp_msforeachtable: '?'でコマンドを実行します 各テーブル名に置き換えられます。例えば

exec sp_msforeachtable "dbcc dbreindex('?')"

テーブルごとに最大3つのコマンドを発行できます

exec sp_msforeachtable
    @Command1 = 'print ''reindexing table ?''',
    @Command2 = 'dbcc dbreindex(''?'')',
    @Command3 = 'select count (*) [?] from ?'

また、 sp_MSforeachdb


2
疑問符を単一引用符で囲むと、クエリでテーブルの名前を取得できます。sp_msforeachtable "select count(*)、 '?' からのtabenmとして?」
ジョディ

51

接続文字列の追加:

MultipleActiveResultSets = true;

これにより、ADO.Net 2.0以降では、単一のデータベース接続で複数の転送専用の読み取り専用結果セットが読み取られるため、大量の読み取りを行っている場合にパフォーマンスを向上させることができます。クエリの種類が混在している場合でも、有効にできます。

アプリケーション名= MyProgramName

sysprocessesテーブルにクエリを実行してアクティブな接続の一覧を表示する場合、プログラムの名前が ".Net SqlClient Data Provider"ではなくprogram_name列に表示されます。


7
会社でアプリケーション名を必須にしました。すべての新しいアプリには一意の名前が必要です。ロック/破損したアプリを簡単に追跡できます。
Neil N

2
アプリケーション名は、プロファイラーのフィルターとしても使用できます。同僚のクエリではなく、クエリのみを表示したい場合に役立ちます。
Mathias F

33

TableDiff.exe

  • Table Differenceツールを使用すると、ソーステーブルと宛先テーブルまたはビューの間の違いを検出して調整できます。Tablediffユーティリティは、スキーマとデータの違いを報告できます。tablediffの最も人気のある機能は、宛先間で実行できるスクリプトを生成して、テーブル間の違いを調整できるという事実です。

リンク


31

ランダムな順序で行を返す、あまり知られていないTSQLテクニック:

-- Return rows in a random order
SELECT 
    SomeColumn 
FROM 
    SomeTable
ORDER BY 
    CHECKSUM(NEWID())

6
小さな結果セットに最適です。十分な時間がない限り、10000行を超えるテーブルでは使用しません
John Sheehan

私はそれよりはるかに大きいテーブルでそれを使用しましたが、それほど遅くはありませんでした。
ミッチウィート

CHECKSUM()の目的は何ですか?NEWID()で注文できます。
ジョナスリンカーン

6
CHECKSUM()なしで、100,000,000(100 mil)行でまともな結果を見たこともあります。また、私は同様に尋ねなければなりません、なぜORDER BY NEWIDではないのですか?
Troy DeMonbreun、2008年

5
@GateKiller:Checksum()は間違いではないため、編集をロールバックしました。ソート列のサイズを縮小します。
ミッチウィート

30

Management Studioでは、次の方法でテーブルの列のカンマ区切りリストをすばやく取得できます。

  1. オブジェクトエクスプローラーで、特定のテーブルの下のノードを展開します(列、キー、制約、トリガーなどのフォルダーが表示されます)。
  2. 列フォルダーをポイントし、クエリにドラッグします。

これは、テーブルを右クリックして[スクリプトテーブルの名前を付けて...]を選択して返される厄介なフォーマットを使用したくない場合に便利です。フォルダーに含まれる名前のコンマ区切りリスト。


23

行コンストラクター

1つのinsertステートメントで複数行のデータを挿入できます。

INSERT INTO Colors (id, Color)
VALUES (1, 'Red'),
       (2, 'Blue'),
       (3, 'Green'),
       (4, 'Yellow')

私はこれに賛成票を投じましたが、MSSQL 2005で試してみましたが、機能しません。2008年のみ?
richardtallent 2009

11
はい、これは2008年の新機能です
。– Rob Boek

2
これは、DB2からSQL Serverに移行したときに見逃した機能です。DB2では、個々の挿入ステートメントの代わりにこれを使用すると、速度が大幅に向上しました
Nathan Koop

22

テーブルの構造、インデックス、制約を知りたい場合:

sp_help 'TableName'

このヒントをショートカットキーと組み合わせてください!最初にテーブル名を強調表示してから、Alt + F1キーを押します
Michael J Swart


20

最も人気のあるクエリを把握する

  • sys.dm_exec_query_statsを使用すると、単一のクエリによるクエリ分析の多くの組み合わせを把握できます。

コマンドとリンクする

select * from sys.dm_exec_query_stats 
order by execution_count desc


16

EXCEPTおよびINTERSECT

複雑な結合とサブクエリを作成する代わりに、これらの2つのキーワードは、2つのクエリ結果を比較するときにクエリの意図を表現する、よりエレガントで簡潔で読みやすい方法です。SQL Server 2005の新機能であり、TSQL言語ですでに長年存在しているUNIONを強力に補完します。

EXCEPT、INTERSECT、UNIONの概念は、すべての最新のRDBMSで使用されるリレーショナルモデリングの基礎と基盤として機能する集合論の基本です。これで、ベン図タイプの結果をTSQLを使用してより直感的かつ簡単に生成できます。


16

完全に隠されているわけではありませんが、PIVOTコマンドについて多くの人が知っているわけではありません。カーソルを使用するストアドプロシージャを変更して、行数の1/10である6秒のコードを実行するのに2分かかりました。


16

テスト目的などでデータベースを復元する場合に役立ちます。ログインIDを正しく再マッピングします。

EXEC sp_change_users_login 'Auto_Fix', 'Mary', NULL, 'B3r12-36'

以前はこのプロシージャが機能していませんでした。オブジェクトの所有権を一時ユーザーに変更し、元のユーザーを削除して、元のユーザーを再度追加し、所有権を割り当て直す必要がありました。Ugh ...
StingyJack 2008年

15

データベースへのすべての接続を削除します。

Use Master
Go

Declare @dbname sysname

Set @dbname = 'name of database you want to drop connections from'

Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(@dbname)
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = min(spid) from master.dbo.sysprocesses
        where dbid = db_id(@dbname) and spid > @spid
End

ワンライナー、またはこれを行うドロップデータベースパラメーターはありますか?UIから「データベースを削除」しようとすると、「既存の接続を閉じる」ためのチェックボックスが表示されます。これは、ブールパラメータであることを示しています。
DevinB 2009

1
実際、私は2行のソリューションを見つけました。ALTER DATABASE [@ DATABASE_NAME @] SET READ_ONLY WITH ROLLBACK IMMEDIATE-すべてのユーザーを切断しますALTER DATABASE [@ DATABASE_NAME @] SET READ_WRITE WITH ROLLBACK IMMEDIATE DROP DATABASE [@ DATABASE_NAME @]
DevinB

1
ALTER DATABASE MyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE新しい接続も発生しなくなります。
ErikE

15

テーブルチェックサム

Select CheckSum_Agg(Binary_CheckSum(*)) From Table With (NOLOCK)

行チェックサム

Select CheckSum_Agg(Binary_CheckSum(*)) From Table With (NOLOCK) Where Column = Value

2
これらにより、テーブル内のすべてのデータのチェックサムを生成できます。これは、2つの行または2つのテーブルが同じであるかどうかを確認する簡単で迅速な方法です。
GateKiller 2008

15

これが非表示の機能であるかどうかはわかりませんが、偶然この機能に遭遇し、多くの場合に役立つことがわかりました。カーソルを使用して選択ステートメントをループするのではなく、単一の選択ステートメントでフィールドのセットを連結できます。

例:

DECLARE @nvcConcatonated nvarchar(max)
SET @nvcConcatonated = ''

SELECT @nvcConcatonated = @nvcConcatonated + C.CompanyName + ', '
FROM tblCompany C
WHERE C.CompanyID IN (1,2,3)

SELECT @nvcConcatonated

結果:

Acme, Microsoft, Apple,

2
COALESCE()を使用して、変数を初期化せずに同じことを行うこともできます。SELECT @nvcConcatonated = COALESCE(@nvcConcatonated + '、'、 '')+ CAST(C.CompanyName as VARCHAR(255))FROM ...
Christopher Klein

これは、更新ステートメントでも機能します。更新されたIDのリストを連結するような場合に役立つことがあります。
EBarr 2011

14

ストアドプロシージャのコードが必要な場合:

sp_helptext 'ProcedureName'

(それが隠し機能であるかどうかはわかりませんが、私はいつもそれを使用しています)


理由はわかりませんが、sp_helptextの出力は、元の非常に長い行では少し間抜けです。Sprocsのスクリプトを作成する場合、これは発生しないので、別の、より堅牢なエクスポートメカニズムがあるのではないでしょうか。sp_helptext 'MyView'も役立ちます。
クリステン、

どういう意味かわかりません。私にとって、SPコードは元のファイルにスクリプトを記述したのと同じ形式で出力されます(すべてのCRなどを含む)
Eduardo Molteni '17

私は正確な詳細を思い出しませんが、それはテキストの保存方法に関係しています-ページサイズについての何かだと私は信じています。出力はほとんど正しいですが、時々、余分な改行が発生します。
RolandTumble 2009

13

ストアドプロシージャのトリックは、INSERTステートメントから呼び出すことができるということです。これは、SQL Serverデータベースで作業しているときに非常に便利であることがわかりました。

CREATE TABLE #toto (v1 int, v2 int, v3 char(4), status char(6))
INSERT #toto (v1, v2, v3, status) EXEC dbo.sp_fulubulu(sp_param1)
SELECT * FROM #toto
DROP TABLE #toto

1
残念ながら、@ TableVariableでは使用できません
クリステン

この非常に便利な手法の問題は、ほとんどの#tablesとは異なり、すべての列を完全に定義する必要があることです。これを行うには、最後に呼び出すproc内に#tableを作成し、次にtempdbでsp_helpを作成し、コピーして貼り付け、procからコードを削除します。完了
アドルフニンニク

12

SQL Server 2005/2008でSELECTクエリの結果に行番号を表示するには:

SELECT ( ROW_NUMBER() OVER (ORDER BY OrderId) ) AS RowNumber,
        GrandTotal, CustomerId, PurchaseDate
FROM Orders

ORDER BYは必須の条項です。OVER()句は、指定された列(この場合はOrderId)でデータをソートし、ソート結果に従って数値を割り当てるようにSQLエンジンに指示します。


SQLエンジンで構文sugerを使用して構文ワードを「RowNumberInTable」として解析した場合、単純ではありません
なし

1
ウィンドウ関数の場合は+1。OVER(PARTITION BY ...)msdn.microsoft.com/en-us/library/ms189461%28v=SQL.100%29.aspx
Matt Stephenson

10

ストアドプロシージャの引数を解析するのに便利です:xp_sscanf

文字列から、各フォーマット引数で指定された引数の場所にデータを読み取ります。

次の例では、xp_sscanfを使用して、ソース文字列の形式での位置に基づいてソース文字列から2つの値を抽出します。

DECLARE @filename varchar (20), @message varchar (20)
EXEC xp_sscanf 'sync -b -fproducts10.tmp -rrandom', 'sync -b -f%s -r%s', 
  @filename OUTPUT, @message OUTPUT
SELECT @filename, @message

これが結果セットです。

-------------------- -------------------- 
products10.tmp        random

4
私はばかげた瞬間を持っている必要があります(いいえ、本当に)。これをどこで使用できるか教えてもらえますか?
Raj More

9

返却日のみ

Select Cast(Floor(Cast(Getdate() As Float))As Datetime)

または

Select DateAdd(Day, 0, DateDiff(Day, 0, Getdate()))

ショートバージョン-SELECT CAST(FLOOR(CAST(@DateTime AS FLOAT))AS DATETIME)
Meff

もちろん。CASTFLOORCASTルール。
StingyJack 2008年

それへの参照が見つかりませんが、SELECT DateAdd(Day、0、DateDiff(Day、0、@DateTime))の方が速いことを示唆したテストを覚えているようです。いずれにせよ、悟りを開いて幸せです!
クリステン、

このsqlteam.com/forums/topic.asp?TOPIC_ID=35296#107617が見つかりましたが、CAST / FLOORメソッドが含まれていませんでした。中規模のレコードセットでの非公式のテストでは、DATEADDはCAST / FLOORよりも約7%速い可能性があることを示唆しています-ほとんどの状況で心配するほどではありません
Kristen

ただし、他の方法を追加しました。私の簡単なテストでは、キャストフロア法の方が800ナノ秒速くなっています。したがって、実際には何もありません。
GateKiller 2009

9

dm_db_index_usage_stats

これにより、テーブルにDateUpdated列がない場合でも、テーブルのデータが最近更新されたかどうかを確認できます。

SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID( 'MyDatabase')
AND OBJECT_ID=OBJECT_ID('MyTable')

コード:http : //blog.sqlauthority.com/2009/05/09/sql-server-find-last-date-time-updated-for-any-table/

参照先情報: SQL Server-テーブルに最後に挿入された行の日付/時刻は何ですか?

SQL 2005以降で利用可能


7

ここに私が便利だと思ういくつかの機能がありますが、多くの人は知らないようです:

sp_tables

現在の環境で照会できるオブジェクトのリストを返します。これは、シノニムオブジェクトを除く、FROM句で使用できるすべてのオブジェクトを意味します。

リンク

sp_stored_procedures

現在の環境のストアドプロシージャのリストを返します。

リンク


7

現在の週のどこかに日付があるレコードを検索します。

where dateadd( week, datediff( week, 0, TransDate ), 0 ) =
dateadd( week, datediff( week, 0, getdate() ), 0 )

先週発生した日付のレコードを検索します。

where dateadd( week, datediff( week, 0, TransDate ), 0 ) =
dateadd( week, datediff( week, 0, getdate() ) - 1, 0 )

現在の週の初めの日付を返します。

select dateadd( week, datediff( week, 0, getdate() ), 0 )

先週の初めの日付を返します。

select dateadd( week, datediff( week, 0, getdate() ) - 1, 0 )

細かいですが、TransDateのインデックスは使用されません。私はむしろ書きたい
vaso

ここで、TransDate> = convert(datetime、floor(convert(float、dateadd(day、-datepart(weekday、@date)+1、@date))))およびTransDate> = convert(datetime、floor(convert(float、dateadd (day、7-datepart(weekday、@date)+1、@date))))
vaso

修正:ここで、TransDate> = convert(datetime、floor(convert(float、dateadd(day、-datepart(weekday、@date)+1、@date))))およびTransDate <convert(datetime、floor(convert(float、 dateadd(day、7-datepart(weekday、@date)+1、@date))))
vaso

7

あまり隠された機能ではありませんが、Tools \ Options \ Keyboardの下のManagement Studioでキーマッピングを設定します。Alt+ F1はデフォルトでsp_help "選択されたテキスト"に設定されていますが、sp_helptext "選択されたテキスト"にCtrl + F1を追加しないとライブできません


私はUSEコマンドの構成にも使用して、データベースに沿って移動します
Jhonny D. Cano -Leftware-

7

永続的な計算された列

  • 計算列は、ランタイム計算コストをデータ変更フェーズにシフトするのに役立ちます。計算列は残りの行と一緒に格納され、計算列の式とクエリが一致したときに透過的に利用されます。PCCにインデックスを作成して、式のフィルタリングと範囲スキャンを高速化することもできます。

リンク


7

並べ替えに適した列がない場合や、テーブルのデフォルトの並べ替え順序が必要で、各行を列挙したい場合があります。そのためには、「(select 1)」を「order by」句に入れると、必要なものが得られます。きちんとね?

select row_number() over (order by (select 1)), * from dbo.Table as t

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.