Funzionalità nascoste di SQL Server


215

Quali sono alcune funzionalità nascoste di SQL Server ?

Ad esempio, stored procedure di sistema non documentate, trucchi per fare cose che sono molto utili ma non abbastanza documentate?


risposte

Grazie a tutti per tutte le ottime risposte!

Procedura di archiviazione

  • sp_msforeachtable: esegue un comando con '?' sostituito con ogni nome di tabella (v6.5 e successive)
  • sp_msforeachdb: esegue un comando con '?' sostituito con ogni nome di database (v7 e versioni successive)
  • sp_who2: proprio come sp_who, ma con molte più informazioni per la risoluzione dei blocchi (da v7 in su)
  • sp_helptext: se vuoi il codice di una procedura memorizzata, visualizza & UDF
  • sp_tables: restituisce un elenco di tutte le tabelle e viste del database nell'ambito.
  • sp_stored_procedures: restituisce un elenco di tutte le procedure memorizzate
  • xp_sscanf: legge i dati dalla stringa nelle posizioni degli argomenti specificate da ciascun argomento del formato.
  • xp_fixeddrives:: trova l'unità fissa con il più grande spazio libero
  • sp_help: se si desidera conoscere la struttura della tabella, gli indici e i vincoli di una tabella. Anche viste e UDF. La scorciatoia è Alt + F1

Frammenti

  • Restituzione di righe in ordine casuale
  • Tutti gli oggetti utente del database per data ultima modifica
  • Solo data di ritorno
  • Trova i record in cui la data cade da qualche parte all'interno della settimana corrente.
  • Trova i record in cui è avvenuta la settimana scorsa.
  • Restituisce la data per l'inizio della settimana corrente.
  • Restituisce la data per l'inizio dell'ultima settimana.
  • Vedere il testo di una procedura che è stata distribuita su un server
  • Rilascia tutte le connessioni al database
  • Tabella Checksum
  • Row Checksum
  • Rilascia tutte le procedure in un database
  • Mappare nuovamente gli ID di accesso correttamente dopo il ripristino
  • Chiamare Stored procedure da un'istruzione INSERT
  • Trova procedure per parola chiave
  • Rilascia tutte le procedure in un database
  • Interrogare il registro delle transazioni per un database a livello di codice.

funzioni

  • HashBytes ()
  • EncryptByKey
  • Comando PIVOT

Varie

  • Extra della stringa di connessione
  • TableDiff.exe
  • Trigger per eventi di accesso (novità in Service Pack 2)
  • Aumentare le prestazioni con persisted-computed-colonne (pcc).
  • Impostazione DEFAULT_SCHEMA in sys.database_principles
  • Parametrizzazione forzata
  • Formato di archiviazione Vardecimal
  • Capire le query più popolari in pochi secondi
  • Database condivisi scalabili
  • Funzionalità Filtro tabella / Stored procedure in SQL Management Studio
  • Bandiere di traccia
  • Numero dopo una GOripetizione del batch
  • Sicurezza mediante schemi
  • Crittografia mediante funzioni di crittografia integrate, viste e tabelle di base con trigger

4
Se noto, sarebbe bello includere le versioni applicabili con ogni risposta. (2000 e fino 2005, 2000., ecc)
bw

C'è molta bontà in questa domanda. Per favore non cancellarlo! :-)
Sklivvz

Risposte:


91

In Management Studio, è possibile inserire un numero dopo un marker di fine batch GO per far sì che il batch venga ripetuto quel numero di volte:

PRINT 'X'
GO 10

Stampa 'X' 10 volte. Questo può salvarti dalla noiosa copia / incolla quando fai cose ripetitive.


70

Molti sviluppatori di SQL Server non sembrano ancora conoscere la clausola OUTPUT (SQL Server 2005 e versioni successive) sull'istruzione DELETE, INSERT e UPDATE.

Può essere estremamente utile sapere quali righe sono state INSERITE, UPDATEd o DELETEd e la clausola OUTPUT consente di farlo molto facilmente - consente l'accesso alle tabelle "virtuali" chiamate insertede deleted(come nei trigger):

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

Se stai inserendo valori in una tabella che ha un campo chiave primaria INT IDENTITY, con la clausola OUTPUT, puoi ottenere immediatamente il nuovo ID inserito:

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

E se stai aggiornando, può essere estremamente utile sapere cosa è cambiato - in questo caso, insertedrappresenta i nuovi valori (dopo l'aggiornamento), mentre deletedfa riferimento ai vecchi valori prima dell'aggiornamento:

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

Se verranno restituite molte informazioni, l'output di OUTPUT può anche essere reindirizzato a una tabella temporanea o a una variabile di tabella ( OUTPUT INTO @myInfoTable).

Estremamente utile - e molto poco conosciuto!

Marc


52

sp_msforeachtable: Esegue un comando con '?' sostituito con ogni nome di tabella. per esempio

exec sp_msforeachtable "dbcc dbreindex('?')"

È possibile emettere fino a 3 comandi per ogni tabella

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

Anche, sp_MSforeachdb


2
È possibile ottenere il nome della tabella nella query utilizzando virgolette singole attorno al punto interrogativo. sp_msforeachtable "seleziona count (*), '?' come tabenm? "
Jody,

51

Extra stringa di connessione:

MultipleActiveResultSets = true;

In questo modo ADO.Net 2.0 e versioni successive leggono set di risultati multipli, di sola lettura e di sola lettura su una singola connessione al database, il che può migliorare le prestazioni se stai leggendo molto. Puoi attivarlo anche se stai eseguendo un mix di tipi di query.

Nome applicazione = NomeProgramma

Ora, quando si desidera visualizzare un elenco di connessioni attive eseguendo una query sulla tabella sysprocesses, il nome del programma verrà visualizzato nella colonna nome_programma invece di ".Net SqlClient Data Provider"


7
Ho reso Application Name un requisito per la mia azienda. Ogni nuova app deve avere un nome univoco. Rende più facile rintracciare l'app bloccata / rotta.
Neil N

2
Il nome dell'applicazione è disponibile anche come filtro nel profiler. Aiuta molto se vuoi vedere solo le tue domande e non quelle dei tuoi colleghi.
Mathias F,

33

TableDiff.exe

  • Lo strumento Differenza tabella consente di scoprire e riconciliare le differenze tra una tabella di origine e di destinazione o una vista. L'utilità Tablediff può segnalare differenze su schema e dati. La caratteristica più popolare di tablediff è il fatto che è in grado di generare uno script che è possibile eseguire sulla destinazione per riconciliare le differenze tra le tabelle.

collegamento


31

Una tecnica TSQL meno nota per la restituzione di righe in ordine casuale:

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

6
Ottimo per piccoli set di risultati. Non lo userei su un tavolo con più di 10000 righe a meno che tu non abbia tempo da perdere
John Sheehan,

L'ho usato su tavoli molto più grandi di così, e non è stato troppo lento.
Mitch Wheat,

Qual è lo scopo di CHECKSUM ()? Puoi ordinare solo con NEWID ().
Jonas Lincoln,

6
Ho anche visto risultati decenti su 100.000.000 (100 milioni) di righe, senza CHECKSUM (). Inoltre, devo chiedere anche, perché non semplicemente ORDINARE DA NEWID?
Troy DeMonbreun,

5
@GateKiller: ho ripristinato la tua modifica, perché Checksum () non è un errore; riduce le dimensioni della colonna di ordinamento.
Mitch Wheat,

30

In Management Studio, è possibile ottenere rapidamente un elenco di colonne delimitate da virgole per una tabella:

  1. In Esplora oggetti, espandi i nodi in una determinata tabella (così vedrai le cartelle per colonne, chiavi, vincoli, trigger ecc.)
  2. Scegliere la cartella Columns e trascinare in una query.

Questo è utile quando non si desidera utilizzare il formato atroce restituito facendo clic con il tasto destro del mouse sulla tabella e selezionando Tabella script come ..., quindi Inserisci in ... Questo trucco funziona con le altre cartelle in quanto ti darà un elenco delimitato da virgole di nomi contenuti nella cartella.


23

Costruttori di file

È possibile inserire più righe di dati con una singola istruzione di inserimento.

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

Ho votato a favore, ma poi l'ho provato in MSSQL 2005 e non funziona. Solo nel 2008?
richardtallent,

11
Sì, è una nuova funzionalità del 2008.
Rob Boek,

2
Questa era una caratteristica che mi mancava quando venivo da DB2 a SQL Server. In DB2, c'è stato un significativo miglioramento della velocità quando si utilizza questa invece delle singole dichiarazioni di inserimento
Nathan Koop,

22

Se vuoi conoscere la struttura della tabella, gli indici e i vincoli:

sp_help 'TableName'

Combina questo suggerimento con il suo tasto di scelta rapida! Evidenzia prima un tablename e poi premi ALT + F1
Michael J Swart il


20

Capire le domande più popolari

  • Con sys.dm_exec_query_stats, puoi capire molte combinazioni di analisi delle query con una singola query.

Collegamento con il commnad

select * from sys.dm_exec_query_stats 
order by execution_count desc


16

TRANNE e INTERSETTO

Invece di scrivere join e sottoquery elaborati, queste due parole chiave sono un modo molto più elegante di abbreviazione e leggibilità per esprimere l'intento della query quando si confrontano due risultati della query. Novità da SQL Server 2005, integrano fortemente UNION che esiste già da anni nel linguaggio TSQL.

I concetti di EXCEPT, INTERSECT e UNION sono fondamentali nella teoria degli insiemi che funge da base e fondamento della modellistica relazionale utilizzata da tutti i moderni RDBMS. Ora, i risultati del tipo di diagramma di Venn possono essere generati in modo più intuitivo e abbastanza semplice usando TSQL.


16

So che non è esattamente nascosto, ma non troppe persone conoscono il comando PIVOT . Sono stato in grado di modificare una procedura memorizzata che utilizzava i cursori e ho impiegato 2 minuti per eseguire un veloce codice di 6 secondi che era un decimo del numero di righe!


16

utile quando si ripristina un database a scopo di test o altro. Mappare nuovamente l'ID di accesso correttamente:

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

Ho avuto questo proc non funzionare prima e ho dovuto cambiare la proprietà degli oggetti in un utente temporaneo, eliminare l'utente originale, riadattare l'originale e riassegnare la proprietà. Ugh ...
StingyJack,

15

Rilascia tutte le connessioni al database:

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

Esiste un one-liner o un parametro drop database che fa questo per me? Ho notato che se si tenta di "eliminare il database" tramite l'interfaccia utente, è presente una casella di controllo per "chiudere le connessioni esistenti" che implica che si tratta di un parametro booleano.
DevinB,

1
In realtà, ho appena trovato una soluzione a due righe. ALTER DATABASE [@ DATABASE_NAME @] SET READ_ONLY CON ROLLBACK IMMEDIATE - questo disconnette tutti gli utenti ALTER DATABASE [@ DATABASE_NAME @] SET READ_WRITE WITH ROLLBACK IMMEDIATE DROP DATABASE [@ DATABASE_NAME @]
DevinB

1
ALTER DATABASE MyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATEeviterà che si verifichino anche nuove connessioni.
ErikE,

15

Tabella Checksum

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

Row Checksum

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

2
Ciò consente di produrre un checksum per tutti i dati nella tabella. È un modo semplice e rapido per verificare se due righe o due tabelle sono uguali.
GateKiller,

15

Non sono sicuro che si tratti di una funzione nascosta o meno, ma mi sono imbattuto in questo e l'ho trovato utile in molte occasioni. È possibile concatonare un insieme di un campo in una singola istruzione select, anziché utilizzare un cursore e scorrere ciclicamente l'istruzione select.

Esempio:

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

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

SELECT @nvcConcatonated

risultati:

Acme, Microsoft, Apple,

2
puoi anche usare COALESCE () per fare la stessa cosa senza la necessità di inizializzare la variabile. SELEZIONA @nvcConcatonated = COALESCE (@nvcConcatonated + ',', '') + CAST (C.CompanyName as VARCHAR (255)) DA ...
Christopher Klein,

Questo funziona anche in una dichiarazione di aggiornamento. A volte utile per fare cose come concatenare un elenco di ID che sono stati aggiornati.
EBarr,

14

Se si desidera il codice di una stored procedure è possibile:

sp_helptext 'ProcedureName'

(non sono sicuro che sia una funzione nascosta, ma la utilizzo sempre)


Non so perché, ma l'output di sp_helptext è un po 'sciocco su tutte le righe troppo lunghe dell'originale. Quando lo scripting Sprocs non accade, quindi forse esiste un altro meccanismo di esportazione più robusto? sp_helptext 'MyView' anche utile.
Kristen,

Non sono sicuro di cosa intendi. Per me, il codice SP viene emesso con lo stesso formato in cui sono stato copiato nel file originale (con tutti i CR, ecc.)
Eduardo Molteni,

Non ricordo il dettagli esatti , ma ha a che fare con il modo in cui il testo viene archiviato, credo sulla dimensione della pagina. L'output è per lo più corretto, ma ogni tanto si ottiene un'interruzione di riga aggiuntiva.
RolandTumble,

13

Un trucco di procedura memorizzata è che è possibile chiamarli da un'istruzione INSERT. L'ho trovato molto utile quando stavo lavorando su un database di 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
Purtroppo non può essere utilizzato con @TableVariable
Kristen il

Il dolore con questa tecnica molto utile è che a differenza della maggior parte dei #tables, devi definire completamente tutte le colonne. Il modo più pigro per farlo è creare la #table all'interno del proc che stai chiamando alla fine, quindi sp_help in tempdb, copia e incolla, rimuovi il codice da proc. Fatto
adolf aglio il

12

In SQL Server 2005/2008 per mostrare i numeri di riga in un risultato della query SELECT:

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

ORDER BY è una clausola obbligatoria. La clausola OVER () indica al motore SQL di ordinare i dati sulla colonna specificata (in questo caso OrderId) e assegnare i numeri secondo i risultati dell'ordinamento.


non sarebbe più semplice se usassero il suger sintattico nel motore sql per analizzare la parola di sintassi come "RowNumberInTable"
nessuno

1
+1 per le funzioni della finestra. Puoi fare cose OLTRE un sottoinsieme di record usando OVER (PARTITION BY ...) msdn.microsoft.com/en-us/library/ms189461%28v=SQL.100%29.aspx
Matt Stephenson

10

Utile per l'analisi degli argomenti della procedura memorizzata: xp_sscanf

Legge i dati dalla stringa nelle posizioni degli argomenti specificate da ciascun argomento del formato.

L'esempio seguente utilizza xp_sscanf per estrarre due valori da una stringa di origine in base alle loro posizioni nel formato della stringa di origine.

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

Ecco il set di risultati.

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

4
Devo avere un momento stupido (no, davvero). Puoi dirmi dove possiamo usarlo?
Raj More,

9

Solo data di ritorno

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

o

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

Versione corta - SELEZIONA CAST (PAVIMENTO (CAST (@DateTime AS FLOAT)) COME DATETIME)
Meff

Diavolo sì. Regole CASTFLOORCAST.
StingyJack,

Non riesco a trovare un riferimento ad esso, ma mi sembra di ricordare che i test che hanno suggerito SELECT DateAdd (Day, 0, DateDiff (Day, 0, @DateTime)) sono stati più veloci. Felice di essere illuminato, in ogni caso!
Kristen,

Ho trovato questo sqlteam.com/forums/topic.asp?TOPIC_ID=35296#107617 ma non includeva il metodo CAST / FLOOR. Un test informale su un recordset di medie dimensioni suggerisce che DATEADD potrebbe essere circa il 7% più veloce di CAST / FLOOR - non abbastanza da preoccuparsi per la maggior parte delle situazioni
Kristen,

Ho aggiunto l'altro metodo, tuttavia; i miei test rapidi mostrano che il metodo del pavimento fuso è di 800 nanosecondi più veloce. Quindi niente davvero.
GateKiller,

9

dm_db_index_usage_stats

Ciò consente di sapere se i dati in una tabella sono stati aggiornati di recente anche se non si dispone di una colonna DateUpdated nella tabella.

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')

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

Informazioni a cui si fa riferimento da: SQL Server - Qual è la data / ora dell'ultima riga inserita di una tabella?

Disponibile in SQL 2005 e versioni successive


7

Ecco alcune funzionalità che trovo utili, ma molte persone non sembrano conoscere:

sp_tables

Restituisce un elenco di oggetti su cui è possibile eseguire una query nell'ambiente corrente. Ciò significa che qualsiasi oggetto che può apparire in una clausola FROM, tranne gli oggetti sinonimo.

collegamento

sp_stored_procedures

Restituisce un elenco di procedure memorizzate nell'ambiente corrente.

collegamento


7

Trova i record in cui la data cade da qualche parte all'interno della settimana corrente.

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

Trova i record in cui è avvenuta la settimana scorsa.

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

Restituisce la data per l'inizio della settimana corrente.

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

Restituisce la data per l'inizio dell'ultima settimana.

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

Bene, ma l'indice su TransDate non verrebbe utilizzato. Preferirei scrivere
vaso

dove TransDate> = convert (datetime, floor (convert (float, dateadd (day, -datepart (dayday, @date) +1, @date)))) e TransDate> = convert (datetime, floor (convert (float, dateadd) (giorno, 7-datepart (giorno della settimana, @data) +1, @data))))
vaso

correzione: dove TransDate> = convert (datetime, floor (convert (float, dateadd (day, -datepart (dayday, @date) +1, @date))))) e TransDate <convert (datetime, floor (convert (float, float, dateadd (giorno, 7-datepart (giorno della settimana, @data) +1, @data))))
vaso

7

Non tanto una funzionalità nascosta, ma l'impostazione di mappature dei tasti in Management Studio in Strumenti \ Opzioni \ Tastiera: Alt + F1 è impostato di default su sp_help "testo selezionato", ma non posso vivere senza l'aggiunta di Ctrl + F1 per sp_helptext "testo selezionato"


Uso anche per configurare il comando USE, per
spostarmi

7

colonne persistuta-calcolato-

  • Le colonne calcolate possono aiutarti a spostare il costo di calcolo del runtime nella fase di modifica dei dati. La colonna calcolata viene archiviata con il resto della riga e viene utilizzata in modo trasparente quando l'espressione sulle colonne calcolate e la query corrispondono. È inoltre possibile creare indici sui PCC per accelerare i filtri e l'intervallo di scansioni sull'espressione.

collegamento


7

Ci sono momenti in cui non esiste una colonna adatta in base alla quale ordinare o si desidera semplicemente l'ordinamento predefinito in una tabella e si desidera enumerare ogni riga. Per fare ciò puoi inserire "(seleziona 1)" nella clausola "ordina per" e otterrai ciò che desideri. Pulito, eh?

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.