Características ocultas de SQL Server

215

¿Cuáles son algunas características ocultas de SQL Server ?

Por ejemplo, los procedimientos almacenados del sistema no documentados, ¿trucos para hacer cosas que son muy útiles pero no están suficientemente documentados?


Respuestas

¡Gracias a todos por todas las excelentes respuestas!

Procedimientos almacenados

  • sp_msforeachtable: ejecuta un comando con '?' reemplazado con cada nombre de tabla (v6.5 y superior)
  • sp_msforeachdb: ejecuta un comando con '?' reemplazado con cada nombre de base de datos (v7 y superior)
  • sp_who2: al igual que sp_who, pero con mucha más información para la resolución de problemas de bloques (v7 y posteriores)
  • sp_helptext: si desea el código de un procedimiento almacenado, vea & UDF
  • sp_tables: devuelve una lista de todas las tablas y vistas de la base de datos en el alcance.
  • sp_stored_procedures: devuelve una lista de todos los procedimientos almacenados
  • xp_sscanf: lee datos de la cadena en las ubicaciones de argumento especificadas por cada argumento de formato.
  • xp_fixeddrives:: encuentre la unidad fija con el mayor espacio libre
  • sp_help: si desea conocer la estructura de la tabla, los índices y las restricciones de una tabla. También vistas y UDF. El atajo es Alt + F1

Fragmentos

  • Devolviendo filas en orden aleatorio
  • Todos los objetos de usuario de la base de datos por última fecha de modificación
  • Fecha de regreso solamente
  • Encuentre registros de qué fecha cae en algún lugar dentro de la semana actual.
  • Encuentra registros de la fecha que ocurrió la semana pasada.
  • Devuelve la fecha para el comienzo de la semana actual.
  • Devuelve la fecha de inicio de la semana pasada.
  • Vea el texto de un procedimiento que se ha implementado en un servidor
  • Descarte todas las conexiones a la base de datos
  • Table Checksum
  • Suma de comprobación de fila
  • Descarte todos los procedimientos en una base de datos
  • Vuelva a asignar los ID de inicio de sesión correctamente después de restaurar
  • Llamar a procedimientos almacenados desde una declaración INSERT
  • Buscar procedimientos por palabra clave
  • Descarte todos los procedimientos en una base de datos
  • Consulte el registro de transacciones para una base de datos mediante programación.

Las funciones

  • HashBytes ()
  • EncryptByKey
  • Comando PIVOT

Misceláneos

  • Cadena de conexión extras
  • TableDiff.exe
  • Desencadenantes para eventos de inicio de sesión (nuevo en Service Pack 2)
  • Aumento del rendimiento con columnas computadas persistentes (pcc).
  • Configuración DEFAULT_SCHEMA en sys.database_principles
  • Parametrización Forzada
  • Formato de almacenamiento vardecimal
  • Resolver las consultas más populares en segundos
  • Bases de datos compartidas escalables
  • Función de filtro de tabla / procedimiento almacenado en SQL Management Studio
  • Trazar banderas
  • Número después de que se GOrepite el lote
  • Seguridad usando esquemas
  • Cifrado utilizando funciones de cifrado integradas, vistas y tablas base con disparadores
Sklivvz
fuente
44
Si se conoce, sería bueno incluir las versiones aplicables con cada respuesta. (2000 en adelante, 2005, 2000 solamente, etc.)
bw
Hay mucha bondad en esta pregunta. ¡Por favor no lo elimines! :-)
Sklivvz

Respuestas:

91

En Management Studio, puede poner un número después de un marcador GO de fin de lote para que el lote se repita esa cantidad de veces:

PRINT 'X'
GO 10

Imprimirá 'X' 10 veces. Esto puede salvarlo de tediosas copias / pegados al hacer cosas repetitivas.

GilM
fuente
70

Muchos desarrolladores de SQL Server todavía no parecen saber acerca de la cláusula OUTPUT (SQL Server 2005 y más reciente) en la declaración DELETE, INSERT y UPDATE.

Puede ser extremadamente útil saber qué filas se han INSERTADO, ACTUALIZADO o ELIMINADO, y la cláusula OUTPUT permite hacer esto muy fácilmente: permite el acceso a las tablas "virtuales" llamadas insertedy deleted(como en los desencadenantes):

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

Si está insertando valores en una tabla que tiene un campo de clave primaria INT IDENTITY, con la cláusula OUTPUT, puede obtener la nueva ID insertada de inmediato:

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

Y si está actualizando, puede ser extremadamente útil saber qué cambió: en este caso, insertedrepresenta los nuevos valores (después de la ACTUALIZACIÓN), mientras se deletedrefiere a los valores anteriores antes de la ACTUALIZACIÓN:

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

Si se devuelve una gran cantidad de información, la salida de OUTPUT también se puede redirigir a una tabla temporal o una variable de tabla ( OUTPUT INTO @myInfoTable).

Extremadamente útil, ¡y muy poco conocido!

Bagazo

marc_s
fuente
52

sp_msforeachtable: Ejecuta un comando con '?' reemplazado con cada nombre de tabla. p.ej

exec sp_msforeachtable "dbcc dbreindex('?')"

Puede emitir hasta 3 comandos para cada tabla

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

También, sp_MSforeachdb

Mitch Wheat
fuente
2
Puede obtener el nombre de la tabla en la consulta utilizando comillas simples alrededor del signo de interrogación. sp_msforeachtable "select count (*), '?' como tabenm de? "
Jody
51

Cadena de conexión extras:

MultipleActiveResultSets = true;

Esto hace que ADO.Net 2.0 y versiones posteriores lean múltiples conjuntos de resultados de solo lectura hacia adelante y solo lectura en una sola conexión de base de datos, lo que puede mejorar el rendimiento si está leyendo mucho. Puede activarlo incluso si está haciendo una combinación de tipos de consulta.

Nombre de la aplicación = MyProgramName

Ahora, cuando desee ver una lista de conexiones activas al consultar la tabla sysprocesses, el nombre de su programa aparecerá en la columna nombre_programa en lugar de ".Net SqlClient Data Provider"

Chris Wenham
fuente
77
Hice el nombre de la aplicación un requisito en mi empresa. Cada nueva aplicación debe tener un nombre único. Hace que rastrear qué aplicación bloqueó / rompió algo sea mucho más fácil.
Neil N
2
El nombre de la aplicación también está disponible como filtro en el generador de perfiles. Ayuda mucho si solo quieres ver tus consultas y no las de tus compañeros de trabajo.
Mathias F
33

TableDiff.exe

  • La herramienta de diferencia de tabla le permite descubrir y conciliar las diferencias entre una tabla o una vista de origen y de destino. La utilidad Tablediff puede informar diferencias en el esquema y los datos. La característica más popular de tablediff es el hecho de que puede generar un script que puede ejecutar en el destino que concilie las diferencias entre las tablas.

Enlace

revs Sklivvz
fuente
31

Una técnica TSQL menos conocida para devolver filas en orden aleatorio:

-- Return rows in a random order
SELECT 
    SomeColumn 
FROM 
    SomeTable
ORDER BY 
    CHECKSUM(NEWID())
Mitch Wheat
fuente
66
Ideal para pequeños conjuntos de resultados. No lo usaría en una mesa con más de 10000 filas a menos que tenga tiempo de sobra
John Sheehan
Lo he usado en mesas mucho más grandes que eso, y no fue demasiado lento.
Mitch Wheat
¿Cuál es el propósito de CHECKSUM ()? Puede ordenar por NEWID ().
Jonas Lincoln
66
Incluso he visto resultados decentes en 100,000,000 (100 mil) filas, sin CHECKSUM (). Además, tengo que preguntar también, ¿por qué no solo ORDENAR POR NEWID?
Troy DeMonbreun
55
@GateKiller: He revertido tu edición, porque Checksum () no es un error; Reduce el tamaño de la columna de clasificación.
Mitch Wheat
30

En Management Studio, puede obtener rápidamente una lista de columnas delimitadas por comas para una tabla:

  1. En el Explorador de objetos, expanda los nodos debajo de una tabla determinada (de modo que verá carpetas para Columnas, Claves, Restricciones, Disparadores, etc.)
  2. Señale la carpeta Columnas y arrastre a una consulta.

Esto es útil cuando no desea utilizar el formato atroz devuelto haciendo clic con el botón derecho en la tabla y eligiendo Tabla de secuencias de comandos como ..., luego Insertar en ... Este truco funciona con las otras carpetas ya que le dará una lista delimitada por comas de nombres contenidos dentro de la carpeta.

Thomas
fuente
23

Constructores de fila

Puede insertar varias filas de datos con una sola instrucción de inserción.

INSERT INTO Colors (id, Color)
VALUES (1, 'Red'),
       (2, 'Blue'),
       (3, 'Green'),
       (4, 'Yellow')
Rob Boek
fuente
Lo voté, pero luego lo probé en MSSQL 2005, y no funciona. ¿Solo 2008?
richardtallent
11
Sí, es una nueva característica de 2008.
Rob Boek
2
Esta fue una característica que me perdí cuando vine de DB2 a SQL Server. En DB2, hubo una mejora significativa de la velocidad al usar esto en lugar de declaraciones de inserción individuales
Nathan Koop, el
22

Si desea conocer la estructura de la tabla, los índices y las restricciones:

sp_help 'TableName'
Eduardo Molteni
fuente
¡Combina este consejo con su tecla de acceso directo! Primero resalte un nombre de tabla y luego presione ALT + F1
Michael J Swart el
22

HashBytes () para devolver el hash MD2, MD4, MD5, SHA o SHA1 de su entrada.

Joel Coehoorn
fuente
¡Buena esa! El enlace correcto es msdn.microsoft.com/en-us/library/ms174415(SQL.90).aspx (versión 2005)
Sklivvz
Tienes razón, esa fue la versión 2008 de los documentos, a pesar de que las páginas son prácticamente idénticas. Corregido ahora.
Joel Coehoorn el
20

Averiguando las consultas más populares

  • Con sys.dm_exec_query_stats, puede descubrir muchas combinaciones de análisis de consultas por una sola consulta.

Enlace con la comunidad

select * from sys.dm_exec_query_stats 
order by execution_count desc
Sklivvz
fuente
16

EXCEPTO e INTERSECTO

En lugar de escribir combinaciones y subconsultas elaboradas, estas dos palabras clave son una forma abreviada mucho más elegante y legible de expresar la intención de su consulta al comparar dos resultados de la consulta. Nuevos a partir de SQL Server 2005, complementan fuertemente UNION, que ya ha existido en el lenguaje TSQL durante años.

Los conceptos de EXCEPTO, INTERSECCIÓN y UNIÓN son fundamentales en la teoría de conjuntos que sirve como base y fundamento del modelado relacional utilizado por todos los RDBMS modernos. Ahora, los resultados del tipo de diagrama de Venn se pueden generar de forma más intuitiva y bastante sencilla utilizando TSQL.

Ray Vega
fuente
16

Sé que no está exactamente oculto, pero no mucha gente sabe sobre el comando PIVOT . ¡Pude cambiar un procedimiento almacenado que usaba cursores y tardé 2 minutos en encontrar un código rápido de 6 segundos que era una décima parte del número de líneas!

Ronald Wildenberg
fuente
16

útil cuando se restaura una base de datos con fines de prueba o lo que sea. Vuelve a asignar correctamente los ID de inicio de sesión:

EXEC sp_change_users_login 'Auto_Fix', 'Mary', NULL, 'B3r12-36'
Kolten
fuente
He tenido este proceso no funciona antes, y tuve que cambiar la propiedad de los objetos a un usuario temporal, descartar el usuario original, volver a agregar el original y asignar la propiedad nuevamente. Ugh ...
StingyJack
15

Descarte todas las conexiones a la base de datos:

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
GateKiller
fuente
¿Hay un parámetro de una línea o un parámetro de base de datos de caída que hace esto por mí? Noto que si intenta 'eliminar la base de datos' a través de la interfaz de usuario, hay una casilla de verificación para 'cerrar conexiones existentes' que implica que es un parámetro booleano.
DevinB
1
En realidad, acabo de encontrar una solución de dos líneas. ALTER DATABASE [@ DATABASE_NAME @] SET READ_ONLY CON ROLLBACK INMEDIATE - esto desconecta a todos los usuarios ALTER DATABASE [@ DATABASE_NAME @] SET READ_WRITE CON ROLLBACK INMEDIATE DROP DATABASE [@ DATABASE_NAME @
02 de
1
ALTER DATABASE MyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATEtambién evitará que se produzcan nuevas conexiones.
ErikE
15

Table Checksum

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

Suma de comprobación de fila

Select CheckSum_Agg(Binary_CheckSum(*)) From Table With (NOLOCK) Where Column = Value
GateKiller
fuente
2
Estos le permiten producir una suma de verificación para todos los datos en la tabla. Es una forma simple y rápida de verificar si dos filas o dos tablas son iguales.
GateKiller
15

No estoy seguro de si esta es una característica oculta o no, pero me topé con esto y he encontrado que es útil en muchas ocasiones. Puede concatenar un conjunto de campos en una sola instrucción de selección, en lugar de usar un cursor y recorrer la instrucción de selección.

Ejemplo:

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

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

SELECT @nvcConcatonated

Resultados:

Acme, Microsoft, Apple,
Sheki
fuente
2
También puede usar COALESCE () para hacer lo mismo sin necesidad de inicializar la variable. SELECCIONE @nvcConcatonated = COALESCE (@nvcConcatonated + ',', '') + CAST (C.CompanyName as VARCHAR (255)) FROM ...
Christopher Klein
Esto también funciona en una declaración de actualización. A veces es útil para hacer cosas como concatenar una lista de ID que se actualizaron.
EBarr
14

Si desea el código de un procedimiento almacenado puede:

sp_helptext 'ProcedureName'

(no estoy seguro si es una función oculta, pero la uso todo el tiempo)

Eduardo Molteni
fuente
No sé por qué, pero la salida de sp_helptext es un poco tonta en cualquier línea demasiado larga en el original. Al programar Sprocs esto no sucede, ¿entonces tal vez hay otro mecanismo de exportación más robusto? sp_helptext 'MyView' también es útil.
Kristen
No estoy seguro de lo que quieres decir. Para mí, el código de los SP está desactualizado con el mismo formato que los he escrito en el archivo original (con todos los CR, etc.)
Eduardo Molteni
No recuerdo los detalles exactos , pero tiene que ver con la forma en que se almacena el texto, algo sobre el tamaño de la página, creo. La salida es en su mayoría correcta, pero de vez en cuando obtienes un salto de línea adicional.
RolandTumble
13

Un truco de procedimiento almacenado es que puede llamarlos desde una instrucción INSERT. Esto me resultó muy útil cuando estaba trabajando en una base de datos de 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
edomaur
fuente
1
Lamentablemente no se puede usar con @TableVariable
Kristen
El problema con esta técnica muy útil es que, a diferencia de la mayoría de las tablas, debe definir completamente todas las columnas. La manera perezosa de hacer esto es crear la #table dentro del proceso al que está llamando al final, luego sp_help en tempdb, copiar y pegar, eliminar el código del proceso. Hecho
Adolf ajo
12

En SQL Server 2005/2008 para mostrar números de fila en un resultado de consulta SELECT:

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

ORDER BY es una cláusula obligatoria. La cláusula OVER () le dice al Motor SQL que ordene los datos en la columna especificada (en este caso, OrderId) y asigne números según los resultados de la ordenación.

Binoj Antony
fuente
no sería más simple si usaran sugerencias sintácticas en el motor sql para analizar su palabra de sintaxis como "RowNumberInTable"
ninguna el
1
+1 para funciones de ventana. Puede hacer cosas SOBRE un subconjunto de registros utilizando OVER (PARTICIÓN POR ...) msdn.microsoft.com/en-us/library/ms189461%28v=SQL.100%29.aspx
Matt Stephenson
10

Útil para analizar argumentos de procedimientos almacenados: xp_sscanf

Lee datos de la cadena en las ubicaciones de argumento especificadas por cada argumento de formato.

El siguiente ejemplo usa xp_sscanf para extraer dos valores de una cadena fuente en función de sus posiciones en el formato de la cadena fuente.

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

Aquí está el conjunto de resultados.

-------------------- -------------------- 
products10.tmp        random
revs Sklivvz
fuente
44
Debo estar teniendo un momento tonto (no, de verdad). ¿Me puede decir dónde podemos usar esto?
Raj More
9

Fecha de regreso solamente

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

o

Select DateAdd(Day, 0, DateDiff(Day, 0, Getdate()))
GateKiller
fuente
Versión corta: SELECT CAST (FLOOR (CAST (@DateTime AS FLOAT)) AS DATETIME)
Meff
Oh sí. Reglas de CASTFLOORCAST.
StingyJack
No puedo encontrar una referencia, pero parece recordar que las pruebas que sugirieron SELECT DateAdd (Day, 0, DateDiff (Day, 0, @DateTime)) fueron más rápidas. ¡Feliz de estar iluminado, de cualquier manera!
Kristen
Encontré este sqlteam.com/forums/topic.asp?TOPIC_ID=35296#107617 pero no incluía el método CAST / FLOOR. Una prueba informal en un conjunto de registros de tamaño mediano sugiere DATEADD puede ser de aproximadamente 7% más rápido que CAST / BAJA - no es suficiente para preocuparse por la mayoría de situaciones
Kristen
Sin embargo, he agregado el otro método; mis pruebas rápidas muestran que el método de piso fundido es 800 nanosegundos más rápido. Así que nada de eso realmente.
GateKiller
9

dm_db_index_usage_stats

Esto le permite saber si los datos de una tabla se han actualizado recientemente, incluso si no tiene una columna de fecha actualizada en la tabla.

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

Código de: http://blog.sqlauthority.com/2009/05/09/sql-server-find-last-date-time-updated-for-any-table/

Información referenciada desde: SQL Server - ¿Cuál es la fecha / hora de la última fila insertada de una tabla?

Disponible en SQL 2005 y posterior

Nathan Koop
fuente
7

Aquí hay algunas características que encuentro útiles, pero muchas personas no parecen conocer:

sp_tables

Devuelve una lista de objetos que se pueden consultar en el entorno actual. Esto significa cualquier objeto que pueda aparecer en una cláusula FROM, excepto los objetos sinónimo.

Enlace

sp_stored_procedures

Devuelve una lista de procedimientos almacenados en el entorno actual.

Enlace

Sklivvz
fuente
7

Encuentre registros de qué fecha cae en algún lugar dentro de la semana actual.

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

Encuentra registros de la fecha que ocurrió la semana pasada.

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

Devuelve la fecha para el comienzo de la semana actual.

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

Devuelve la fecha de inicio de la semana pasada.

select dateadd( week, datediff( week, 0, getdate() ) - 1, 0 )
GateKiller
fuente
Bien, pero el índice en TransDate no se usaría. Prefiero escribir
vaso
donde TransDate> = convert (datetime, floor (convert (float, dateadd (día, -datepart (día de la semana, @date) +1, @date)))) y TransDate> = convert (datetime, floor (convert (float, dateadd (día, 7-datepart (día de la semana, @date) +1, @date))))
vaso
corrección: donde TransDate> = convert (datetime, floor (convert (float, dateadd (día, -datepart (día de la semana, @date) +1, @date)))) y TransDate <convert (datetime, floor (convert (float, dateadd (día, 7-datepart (día de la semana, @date) +1, @date))))
vaso
7

No es tanto una función oculta sino configurar asignaciones de teclas en Management Studio en Herramientas \ Opciones \ Teclado: Alt + F1 está predeterminado en sp_help "texto seleccionado" pero no puedo vivir sin agregar Ctrl + F1 para sp_helptext "texto seleccionado"

JohnD
fuente
También uso para configurar el comando USE, para moverme a lo largo de los db's
Jhonny D. Cano -Leftware-
7

Columnas calculadas persistentes

  • Las columnas calculadas pueden ayudarlo a cambiar el costo de cálculo del tiempo de ejecución a la fase de modificación de datos. La columna calculada se almacena con el resto de la fila y se utiliza de forma transparente cuando la expresión en las columnas calculadas y la consulta coinciden. También puede crear índices en los PCC para acelerar las filtraciones y escanear el rango de la expresión.

Enlace

Sklivvz
fuente
7

Hay momentos en que no hay una columna adecuada para ordenar, o simplemente desea el orden de clasificación predeterminado en una tabla y desea enumerar cada fila. Para hacerlo, puede poner "(seleccione 1)" en la cláusula "ordenar por" y obtendrá lo que desea. Aseado, ¿eh?

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