Como insertar filas en una tabla con identity?

A veces se ocupa poder insertar filas que se traen de una estructura vieja y hemos definido con anterioridad una columna con un identity. En estas ocasiones se hace necesario deshabilitar el comportamiento del identity.

Para lograrlo tenemos que hacer lo siguiente.

  1. Ejecutar el comando [SET IDENTITY_INSERT dbo.MiTabla ON;]
  2. Ejecutar un insert into, en este caso hago enfasis en que es necesario enumerar el nombre de la columna tanto en el insert como en la seccion del select.
SET IDENTITY_INSERT dbo.MiTabla ON;
GO
Insert into MiTabla (ID, Col1, Col2)
select ID, Col1, Col2
from MiTabla_old
where id> 1000
GO
SET IDENTITY_INSERT dbo.MiTabla OFF;

Es importante rescatar que cuando inserto estas nuevas filas el valor del identity se modificara a valor mas alto insertado.

Para validar el valor actual de la columna identity solamente necesitamos ejecutar el comando [DBCC CHECKIDENT], como se aprecia en el próximo ejemplo.

DBCC CHECKIDENT('MiTabla', NORESEED)

Como renombrar una instancia de SQL

Esto es algo que realmente que uso poco, pero ciertamente me ha sido bastante util en ambientes de pruebas cuando el nombre de maquina difiere del nombre de instancia y por alguna razon en particular ocupo que sean el mismo.

Antes de renombrar tenemos que descartar lo siguiente:

  1. No usamos replicacion
  2. No existen logins de acceso remoto

El codigo de la siguiente seccion nos permitira validar estas dos condiciones:

DECLARE @txt VARCHAR(512)

SET @txt = ''

IF EXISTS(
SELECT *
FROM sys.databases
where is_published = 1 or is_subscribed =1 or is_distributor = 1
)
BEGIN
SET @txt = 'No se podra renombrar por el momento, Existe Replicacion'
END

IF EXISTS(
select *
from sys.remote_logins a
INNER JOIN sys.sysservers b on b.srvid = a.server_id
)
BEGIN
IF(@txt = '')
BEGIN
SET @txt = 'No se podra renombrar por el momento, existen [Remote Logins]'
END
ELSE
BEGIN
SET @txt = '
No se podra renombrar por el momento, existen [Remote Logins]'
END
END

IF @txt = ''
BEGIN
SET @txt = 'No existen problemas para ejecutar el sp_dropserver'
END
Print @txt

A continuacion lo que hay que hacer es buscar el nombre actual de la maquina. Lo que siempre hago es buscarlo abriendo una ventana del command prompt, y utilizando el comando hostname.

Solo quedaria correr el sp_dropserver y el sp_addserver

<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>
DECLARE @oldname sysname
DECLARE @newname sysname

SET @oldname = 'server'
SET @newname = 'newserver'

EXEC sp_dropserver
@server = @oldname
--nombre de la instancia, tipo sysname, no acepta espacios
--@droplogins = ''
--Permite Remover los Remote Logins de la insntancia

EXEC sp_addserver
@server = @newname
--nombre de la instancia, tipo sysname, no acepta espacios
,@local = local
--indica si la insntacia es local, varchar(1)
--Cuando se asigna LOCAL le indica al SQL que el nombre
--de instacia es lo que le enviamos a @server
--,@duplicate_ok =
--Permite nombres de instancia duplicados
--Solo tiene to valores posibles duplicate_OK o NULL
--Nunca lo he usado
GO

Nota: en caso de renombrar una instancia nombrada, cambiamos el los valores
@oldname y @newname incluyendo el nombre de la maquina y el de la instancia de la siguiente manera:

SET @oldname = 'server\instance'
SET @newname = 'server\newinstance'

El nombre del servidor tambien puede cambiarse

Fuente:
MS Drop Server
MS addServer

Leer, buscar y filtrar el contenido del log de errores

Algunas veces se hace complicado encontrar lo que buscamos en el Log de SQL Server, debido a los muchos registros de información que se llevan a cabo por parte del sistema (auditorias de seguridad, ejecución de respaldos, etc)

--SIN FILTROS
EXEC xp_readerrorlog

Ejecutar la instruccion sin ningun filtro nos va a generar la misma cantidad de informacion tan abrumadora de la interfaz grafica. Dichosamente el procedimiento tiene parametros para filtrar la informacion:

  • Parametro #1 –
    • Se usa para identificar el archivo a consultar.
    • MSSQL guarda una cantidad configurable de archivos de registro de eventos, y se crea uno nuevo con cada registro Sin no se envia ningun valor en este parametro siempre se revisara el actual cuyo valor es de 0
  • Parametro #2 –
    • Es un filtro para incluir eventos del motor o del Agente
      • 1 = SQL Server error log (default)
      • 2 = SQL Agent log
  • Parametro #3 –
    • Es un filtro de busqueda del tipo NChar
  • Parametro #4 –
    • Es un filtro adicional de busqueda del tipo NChar
  • Parametro #5 –
    • Es un filtro de busqueda por fecha, en el que se incluyen los errores anteriores a la fecha definida
  • Parametro #6 –
    • Es un filtro de busqueda por fecha, en el que se incluyen los errores posteriores a la fecha definida
  • Parametro #7 –
    • Es un parametro para definir el ordenamiento de la informacion
      • – N’ASC’
      • – N’DESC’
--Con Filtros
EXEC xp_readerrorlog 0, 1, NULL, NULL, NULL, NULL, N'ASC'

La imagen que esta justo debajo de este texto es un ejemplo de la instancia que tengo instalada en mi maquina personal, y se muestran miles de miles de filas de informacion en una maquina de escritorio; que puede depararnos un server productivo con cientos, miles o millones de transacciones diarias.

SQL Server Error Log

Ref:

https://blogs.msdn.microsoft.com/askjay/2010/09/19/the-parameters-of-xp_readerrorlog/

Encontrar las dependencias en mi base de datos

Escribe esta consulta temprano para buscar las dependencias de un procedimiento que estaba modificando, pude haber utilizado el sp_depends para que me liste todas las dependencias pero no me hubiese listado los totales que es lo que realmente estaba buscando.

SELECT DISTINCT
OBJECT_NAME(o.object_id) ,
v.name ,
COUNT(1)
FROM
sys.objects o
INNER JOIN master.dbo.spt_values v ON o.type = SUBSTRING(v.name, 1, 2) COLLATE catalog_default
AND v.type = 'O9T'
INNER JOIN sys.sql_dependencies d ON o.object_id = d.object_id
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE
o.object_id = OBJECT_ID('<MIPROCEDIMIENTO>')
AND d.class < 2
GROUP BY
OBJECT_NAME(o.object_id) ,
v.name
ORDER BY
3 DESC;
GO


sp_depends '<MIPROCEDIMIENTO>';</pre>
<pre>

sp_executesql vrs sp_sqlexec

Estos procedimientos son utilizados comúnmente para ejecutar codigo Transact de manera dinamica; es codigo que armamos a partir de hileras para producir un producto que de otra forma seria un poco complicado.

sp_sqlexec esta en desuso, es un procedimiento que MSSQL ya no soporta y por tanto se deberia de reescribir cualquier codigo que lo este utilizando en este momento.

Cuando ejecutamos codigo dinamico podemos usar sp_executesql o bien exec. Con la diferencia de que el sp_executesql probablemente creara un plan de ejecucion que se pueda reutilizar para ejecuciones posteriores.

Sintaxis


USE master
GO

DECLARE @vsql NVARCHAR(max)

SET @vsql = 'select top 210 * from sys.tables'

EXEC(@vsql)

EXEC sys.sp_sqlexec @vsql

EXEC sys.sp_executesql @vsql

Como exportar los diagramas de bases de datos de MSSQL

Esta semana estuvimos trabajando en presentaciones en el trabajo y estuve buscando una manera rápida de exportar los diagramas de base datos a una aplicación donde pudiese modificarlos de una mejor manera; lo aprendido en dos simples lineas.

1. Si se piensa o se necesita mover estos diagramas a otra base de datos, lo mejor es crearlos en una herramienta como el MS Visio que te permite crear diagramas entidad relación o relacionales y de ahí exportarlos a SQL.

2. Si ya se crearon los diagramas, no existe una manera simple de exportarlos a ninguna herramienta después del Visio 2010, el Visio 2013 a mi entender es menos robusto en estas funcionalidades. No queda mas que copiar el diagrama, para hacer esto simplemente se tiene que editar el diagrama, ya cuando estamos en modo de edición simplemente vamos al menú Diagrama de Bases de datos [Database Diagram] y elegimos la opción Copiar el diagrama al porta papeles [Copy Diagram to Clipboard]; esto nos genera una imagen a partir del diagrama no es editable pero sirve para presentaciones.

Espero sea útil.

Script para listar permisos

Esto no es algo nuevo, en realidad tengo mucho tiempo de tener este codigo. Y otras veces me fue super util. Hoy de hecho me funciono en el trabajo cuando necesitaba replicar permisos de una base de datos que tuvimos que cambiar de un servidor a otros.

SELECT 
		[Permisos] = state_desc 
			+ ' ' + permission_name 
			+ ' on [' + c.name
			+ '].[' + b.name 
			+ '] to [' + ar.name 
			+ ']' COLLATE latin1_general_ci_as
FROM 
	sys.database_permissions AS a
	INNER JOIN sys.objects AS b 
		ON a.major_id = b.object_id
	INNER JOIN sys.schemas AS c 
		ON b.schema_id = c.schema_id
	INNER JOIN sys.database_principals AS ar 
		ON a.grantee_principal_id = ar.principal_id
UNION
SELECT 
		[Permisos] = state_desc 
			+ ' ' + permission_name 
			+ ' on Schema::['+ c.name 
			+ '] to [' + ar.name 
			+ ']' COLLATE latin1_general_ci_as
FROM 
	sys.database_permissions AS a
	INNER JOIN sys.schemas AS c 
		ON a.major_id = c.schema_id AND a.class_desc = 'Schema'
	INNER JOIN sys.database_principals AS ar 
		ON a.grantee_principal_id = ar.principal_id
		

Automatic Index Tuning in SQL Server Using the Missing Index Dynamic Management Views

Este es un artículo de lo más interesante. Talvez no sea lo que uno quisiera hacer en sus ambientes. Pero en casos en los que no podes mejorar el rendimiento de las consultas por no tener acceso a la maquina

Avatar de jmdorityJustin M. Dority on Development

In many cases, a DBA may not have access to your deployed databases (if they are deployed to customer sites), may not be able to predict which indexes will help most in ad-hoc reporting databases, or simply may not have the time to hand-tune indexes on all of your databases. To help DBAs with tuning indexes, the missing index Dynamic Management Views (DMVs) were introduced in SQL Server 2005, but they only provide suggestions, there is no built-in facility to automate index tuning. However, with a small T-SQL script, you can put some of your databases on autopilot, and hopefully provide a better experience for your users.

Once again, there is no replacement for an experienced DBA with knowledge of your data and usage patterns performing tuning, but if you don’t have a DBA available for your database, just want a little guidance in which indexes are needed, or you…

Ver la entrada original 383 palabras más

Cual job se esta ejecutando???

Hoy ocupaba una consulta rápida para una validación, y la verdad buscando en red me encontré un código rápido y bastante útil para encontrar los jobs o tareas programadas en ejecución, el original esta en esta pagina (http://www.sanssql.com/2013/08/t-sql-query-to-find-currently-running.html), la verdad lo único que modifique fueron las etiquetas. No es postear por postear, la verdad si me fue bastante útil en lo que ocupaba, tal ves lo sea para alguien mas

SELECT
    J.name AS 'Nombre del Job',
    ja.start_execution_date AS 'Inicio a las:',
    DATEDIFF(ss, ja.start_execution_date, GETDATE()) AS 'Ha corrido por: (Segundos)'
FROM msdb.dbo.sysjobactivity ja
     INNER JOIN msdb.dbo.sysjobs J ON J.job_id=ja.job_id
WHERE job_history_id IS NULL AND ja.start_execution_date IS NOT NULL
ORDER BY start_execution_date;

Este otro da un poco mas de info

SELECT
	J.name AS 'Nombre del Job',
	ja.start_execution_date AS 'Inicio a las:',
	DATEDIFF(ss, ja.start_execution_date, GETDATE()) AS 'Ha corrido por: (Segundos)'
FROM msdb.dbo.sysjobactivity ja
	 INNER JOIN msdb.dbo.sysjobs J ON J.job_id=ja.job_id
WHERE job_history_id IS NULL AND ja.start_execution_date IS NOT NULL
ORDER BY start_execution_date;Otra version un poco mas de detalle


SELECT 
    [sj].[job_id] AS [ID]
    , [sj].[name] AS [Nombre]
    , CASE 
        WHEN [jh].[run_date] IS NULL OR [jh].[run_time] IS NULL THEN NULL
        ELSE CAST(
                CAST([jh].[run_date] AS CHAR(8))
                + ' ' 
                + STUFF(
                    STUFF(RIGHT('000000' + CAST([jh].[run_time] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':')
                AS DATETIME)
      END AS [UltimaFechaEjecucion]
    , CASE [jh].[run_status]
        WHEN 0 THEN 'Fallido'
        WHEN 1 THEN 'Completado'
        WHEN 2 THEN 'Reintento'
        WHEN 3 THEN 'Cancelado'
        WHEN 4 THEN 'Ejecutando' -- In Progress
      END AS [EstadoUltimaEjecucion]
    , STUFF(STUFF(RIGHT('000000' + CAST([jh].[run_duration] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':') 
        AS [DuracionUltimaEjecucion(HH:MM:SS)]
    , [jh].[message] AS [EstadoDeLaUltimaEjecucion]
    , [jh].[last_executed_step_id] [IDUltimoPasoEjecutado]
    , [jh].[last_executed_step] [UltimoPasoEjecutado]
	, CASE [sJOBSCH].[NextRunDate]
        WHEN 0 THEN NULL
        ELSE CAST(
                CAST([sJOBSCH].[NextRunDate] AS CHAR(8))
                + ' ' 
                + STUFF(STUFF(RIGHT('000000' + CAST([sJOBSCH].[NextRunTime] AS VARCHAR(6)),  6), 3, 0, ':'), 6, 0, ':') AS DATETIME)
      END AS [FechaProximaEjecucion]
FROM 
    [msdb].[dbo].[sysjobs] AS [sj]
    LEFT JOIN (
                SELECT
                    [job_id]
                    , MIN([next_run_date]) AS [NextRunDate]
                    , MIN([next_run_time]) AS [NextRunTime]
                FROM [msdb].[dbo].[sysjobschedules]
                GROUP BY [job_id]
            ) AS [sJOBSCH]
        ON [sj].[job_id] = [sJOBSCH].[job_id]
    LEFT JOIN (
                SELECT 
                    [sjh].[job_id]
                    , [sjh].[run_date]
                    , [sjh].[run_time]
                    , [sjh].[run_status]
                    , [sjh].[run_duration]
                    , [sjh].[message]
                    , ROW_NUMBER() OVER (
                                            PARTITION BY sjh.[job_id] 
                                            ORDER BY [sjh].[run_date] DESC, [sjh].[run_time] DESC
                      ) AS RowNumber
					, [sja].[last_executed_step_id]
					, [sjs].[step_name] [last_executed_step]
					, [sja].[last_executed_step_date]
                FROM [msdb].[dbo].[sysjobhistory] sjh
					LEFT OUTER JOIN [msdb].[dbo].[sysjobactivity] sja ON sja.job_id = sjh.job_id
					LEFT OUTER JOIN [msdb].[dbo].[sysjobsteps] sjs ON sjs.job_id = sja.job_id AND sjs.step_id = sja.last_executed_step_id
                WHERE sjh.[step_id] = 0
            ) AS [jh]
        ON [sj].[job_id] = [jh].[job_id]
        AND [jh].[RowNumber] = 1
ORDER BY [Nombre]

Como medir el progreso del rollback de una transaccion

Muchas veces nos encontramos con casos de consultas (queries) que estan modificando datos por largos periodos de tiempo y honestamente lo ultimo que quiero hacer en esos momentos es terminar el proceso; si se da el caso que el Log de la base de datos se lleno es preferible crear un log temporal en otra unidad y esperar a que la transacción termine por si misma. Pero si se da el caso que no podemos esperar y hay que terminar o matar la transacción ya tenemos a nuestro jefe o cliente presionando por ello, siempre es util saber cual es el % del progreso del rollback, para ello utilizamos el mismo comando KILL <SPID> WITH STATUSONLY, este comando nos dara un estimado del porcentaje.

Para reproducir, generar un ciclo de inserción en cualquier tabla, en este ejemplo insertamos texto infinitamente:


CREATE TABLE tprueba
(
id    INT NOT NULL IDENTITY(1, 1),
texto VARCHAR(15),
CONSTRAINT pk_tprueba PRIMARY KEY (id)
)

WHILE EXISTS(SELECT 1
FROM   sys.tables
WHERE  name = 'Tprueba')
BEGIN
INSERT INTO tprueba
VALUES      (' Es Una Prueba ')
END

Una vez que tengamos el código en ejecución procedamos a matar o terminar la transacción que recien iniciamos


KILL <SPID>

Una vez en estado rollback ejecutamos la misma instrucción de KILL con el parámetro [statusonly]

KILL <spid> WITH statusonly