2015/07/27

DEFAULT INSTANCE, NAMED INSTANCE

PROBLEMA
En algunas ocasiones será necesario instalar más de una instancia SQL SERVER en nuestro servidor, uno de los pasos que tenemos que tomar en cuenta es que debemos identificar a que instancia nos estamos conectando. Lo primero que debemos identificar es cuantas instancias tenemos instaladas, que puerto están utilizando para escuchar, si es una DEFAULT INSTANCE o una NAMED INSTANCE, entre algunas otras.

ALGO DE TEORIA
Alguna de las características de ambas son las siguientes:

DEFAULT INSTANCE
  • Por default se conecta a través del puerto 1433, puede ser otro, solo es necesario configurarlo.
  • No es necesario especificar el número de puerto al momento de realizar la conexión, siempre y cuando sea el puerto 1433.
  • No es necesario especificar el nombre de la instancia, mientras utilice el puerto 1433.
  • El nombre de dicha instancia se creará como MSSQLSERVER.
  • Solo puede haber una por cada servidor.

NAMED INSTANCE
  • Se crean usando un puerto dinámico que no esté siendo usado por el servidor, puede ser modificado inclusive utilizando el puerto 1433, tomando en cuenta que solo podemos usar una instancia por puerto, de lo contrario marcará un error.
  • Requiere especificar el número de puerto al momento de realizar la conexión, en caso de usar el puerto 1433, no es necesario especificarlo.
  • El nombre de la instancia es asignada al momento de la instalación.
  • Pueden existir cierta cantidad de instancias en un mismo servidor.

SOLUCION

Como configurar el puerto de una DEFAULT INSTANCE

1.- Abrimos en nuestro servidor el SQL SERVER CONFIGURATION MANAGER, como pueden observar yo tengo instaladas 2 NAMED INSTANCEs ( SQLSERVER2012 y SQLSERVER2014 ) y 1 DEFAULT INSTANCE ( MSSQLSERVER ). Por el momento solo requerimos que el servicio SQL Server correspondiente a la DEFAULT INSTANCE se encuentre corriendo, si hacemos alguna modificación recuerden que es necesario reiniciar el servicio.

2.- Damos click sobre los protocolos de la DEFAULT INSTANCE, solo se requiere que el protocolo TCP/IP se encuentre habilitado, después explicaré para que funcionan los otros protocolos.

3.- Hacemos doble click sobre TCP/IP  y vamos a la pestaña IP Adressess, solo verificamos que la IP del equipo se encuentre en la parte de IP2 y en la parte de IPAll, en la propiedad TCP Port se encuentre escrito el puerto 1433 y en TCP Dynamic Ports se encuentre en blanco.

Si hicimos alguna modificación, es necesario Reiniciar el servicio SQL Server( MSSQLSERVER ) y ahora si podemos probar:

Ahora bien, ya estamos conectados, pero como sabemos cual es la instancia a la que estamos conectados, podemos probar con la siguiente consulta:
SELECT @@SERVICENAME AS instanceName
, SERVERPROPERTY('InstanceName') AS instanceName2
, SERVERPROPERTY('ServerName') AS serverName
, local_tcp_port AS puerto
FROM   sys.dm_exec_connections
WHERE  session_id = @@SPID


Solo que debemos tomar algo en cuenta, MSDN en línea dice lo siguiente con respecto a la propiedad InstanceName con la función SERVERPROPERTY: Regresa NULL si el nombre de la instancia es la DEFAULT, si el valor de entrada es incorrecto o error, es por ello que obtenemos NULL, pero con @@SERVICENAME podemos obtener el nombre de la instancia a la que estamos conectados.

DEFAULT INSTANCE USANDO OTRO PUERTO

Ahora bien, podemos conectarnos a nuestro DEFAULT INSTANCE con otro puerto? CLARO!, solo debemos configurarlo en el SQL SERVER CONFIGURATION MANAGER nuevamente y esta vez indicar el número de puerto al realizar la conexión, para el ejemplo usaré el puerto 1010, recuerden verificar que el puerto no esté siendo utilizado o deshabilitar el FIREWALL o agregarlo en la lista de puertos en el mismo FIREWALL.

Si intentamos conectarnos sin usar el puerto obtendremos:

Ahora bien, en mi caso tengo 2 NAMED INSTANCE más instaladas en el mismo equipo, SQLSERVER2012 y SQLSERVER2014, lo que haré es configurar la primera en el puerto para una DEFAULT INSTANCE ( 1433 ) y la segunda en un puerto por ejemplo el 1020. En el caso de la primera no será necesario especificar el puerto al momento de realizar la conexión por que está usando el puerto DEFAULT.

NAMED INSTANCE: SQLSERVER2012, puerto 1433 (DEFAULT)

NAMED INSTANCE: SQLSERVER2014, puerto 1020.

No olvidemos iniciar los servicios correspondientes para cada instancia:

Probamos todas las conexiones:
DEFAULT INSTANCE: MSSQLSERVER, puerto: 1010

NAMED INSTANCE: SQLSERVER2012, puerto 1433(DEFAULT)

NAMED INSTANCE: SQLSERVER2014, puerto 1020

De esta manera, tenemos 3 instancias en nuestro servidor, pueden configurarlos de la manera que gusten, como pudieron observar una DEFAULT INSTANCE no requiere de usar siempre el puerto DEFAULT 1433, puede utilizar algún otro. En otro artículo les explicaré como pueden conectarse utilizando solo el nombre del equipo y el nombre de la instancia a la que desean conectarse, ejemplo: nombreEquipo\SQLSERVER2012 .

SALUDOS!

2015/07/24

CONEXIONES REMOTAS

Es este uno de los temas principales cuando estamos iniciando en este mundo, una vez que ya he instalado mi servidor SQL SERVER, me conecto a el de manera fácil utilizando el SQL SERVER MANAGEMENT STUDIO, utilizando la IP que le indicamos al servidor e inicialmente con el SA ( System Administrator ), pero… sorpresa  ¡ ¡ Obtenemos el siguiente error:


Como podemos solucionar dicho problema, de la siguiente manera:

1.- Abrimos nuestro SQL SERVER CONFIGURATION MANAGER.

2.- Desplegamos SQL Server Network Configuration, Protocols for [nombreInstancia] y debemos tener habilitado el protocolo TCP/IP y después damos doble click sobre dicho protocolo 

3.- Después iremos hacia IP Adresses y en la parte IP2 debemos ingresar la IP de nuestro equipo donde instalemos el SQL SERVER y en la parte de abajo en la sección IPAll, debemos observar detenidamente el puerto que fue asignado, en mi caso es 49188, que utilizaremos para conectarnos.

4.- Damos aplicar y OK, nos pedirá reiniciar el servicio SQL SERVER ( o iniciar el servicio ) para que los cambios surtan efecto.

5.- Con esto ya podemos conectarnos, para esto requerimos la IP y el puerto que les comentaba anteriormente.

6.- Ahora si no deseamos introducir un puerto, podemos utilizar el default o el nombre de una instancia, pero para el segundo lo explicaré en un siguiente artículo, veamos el primer caso, que sería utilizando un puerto predeterminado que es el 1433, regresamos a nuestro SQL SERVER CONFIGURATION MANAGER y en la parte también de los protocolos de nuestra instancia, en el protocolo TCP/IP, nuevamente en la sección TCP Port, dejamos en blanco la propiedad TCP Dynamic Ports y  en TCP Port escribimos 1433.

7.- Solo basta reiniciar nuevamente el servicio y ahora probamos conectando al servidor sin el puerto:

De esta manera podemos permitir las conexiones remotas a nuestro servidor, si el servidor tiene un FIREWALL, pueden leer este artículo que escribí donde les indicó como pueden lograr conectarse a un servidor con el FIREWALL activado

SALUDOS!!

2015/07/07

USANDO FOREACH LOOP CONTAINER EN SSIS

Hace algunos días, un compañero de trabajo tenía la necesidad de actualizar los datos de varias tablas a través de SSIS: cada tabla tenía la misma estructura que las otras y los nombres de las tablas estaban almacenados en otra tabla, entonces lo que pensé fue en recorrer el contenido de la tabla donde se encontraban los nombres y construir la cadena mediante una expresión de otra variable más.

Es posible que existan otras soluciones, aquí les dejo lo que hice:
-- CREANDO LA TABLA QUE CONTIENE LOS NOMBRES DE LAS TABLAS
IF OBJECT_ID( 'dbo.catTablas' ) IS NOT NULL
 DROP TABLE dbo.catTablas;
GO
CREATE TABLE dbo.catTablas(
 cve INT IDENTITY( 1,1 )
 , nombreTabla VARCHAR(50)
)
GO

-- CREANDO LAS TABLAS QUE SERAN MODIFICADAS POSTERIORMENTE
IF OBJECT_ID( 'dbo.tabla1') IS NOT NULL
 DROP TABLE dbo.tabla1;
GO

CREATE TABLE dbo.tabla1(
 cve INT IDENTITY( 1,1 )
 , descripcion VARCHAR(50)
);
GO

IF OBJECT_ID( 'dbo.tabla2') IS NOT NULL
 DROP TABLE dbo.tabla2;
GO
CREATE TABLE dbo.tabla2(
 cve INT IDENTITY( 1,1 )
 , descripcion VARCHAR(50)
);
GO

IF OBJECT_ID( 'dbo.tabla3') IS NOT NULL
 DROP TABLE dbo.tabla3;
GO
CREATE TABLE dbo.tabla3(
 cve INT IDENTITY( 1,1 )
 , descripcion VARCHAR(50)
);
GO

IF OBJECT_ID( 'dbo.tabla4') IS NOT NULL
 DROP TABLE dbo.tabla4;
GO
CREATE TABLE dbo.tabla4(
 cve INT IDENTITY( 1,1 )
 , descripcion VARCHAR(50)
);
GO

IF OBJECT_ID( 'dbo.tabla5') IS NOT NULL
 DROP TABLE dbo.tabla5;
GO
CREATE TABLE dbo.tabla5(
 cve INT IDENTITY( 1,1 )
 , descripcion VARCHAR(50)
);
GO

-- INSERTANDO LOS NOMBRES DE LAS TABLAS
INSERT INTO dbo.catTablas
VALUES( 'dbo.tabla1') , ( 'dbo.tabla2'), ( 'dbo.tabla3') , ( 'dbo.tabla4') , ( 'dbo.tabla5')
GO

-- INSERTANDO ALGUNOS DATOS EN LAS TABLAS
INSERT INTO dbo.tabla1
VALUES( 'descripcion de la cve 1 de la tabla 1' )
, ( 'descripcion de la cve 2 de la tabla 1' );
GO

INSERT INTO dbo.tabla2
VALUES( 'descripcion de la cve 2 de la tabla 2' )
, ( 'descripcion de la cve 2 de la tabla 2' );
GO

INSERT INTO dbo.tabla3
VALUES( 'descripcion de la cve 1 de la tabla 3' )
, ( 'descripcion de la cve 2 de la tabla 3' );
GO

INSERT INTO dbo.tabla4
VALUES( 'descripcion de la cve 1 de la tabla 4' )
, ( 'descripcion de la cve 2 de la tabla 4' );
GO

INSERT INTO dbo.tabla5
VALUES( 'descripcion de la cve 1 de la tabla 5' )
, ( 'descripcion de la cve 2 de la tabla 5' );
GO

-- CONSULTANDO EL RESULTADO
SELECT * FROM dbo.catTablas;

SELECT * FROM dbo.tabla1;
SELECT * FROM dbo.tabla2;
SELECT * FROM dbo.tabla3; 
SELECT * FROM dbo.tabla4;
SELECT * FROM dbo.tabla5;
Una vez que hayan ejecutado el script anterior, procederemos a crear un nuevo paquete DTSx y crearemos algunas variables, para esto necesitaremos 1 variable para almacenar el resultado de la consulta a nuestra tabla que contiene los nombres de las otras tablas, 1 variable para construir la cadena SQL y, para el ejemplo, necesitaremos otras 2 variables más para almacenar el contenido de las columnas, este número depende de la cantidad de columnas que necesiten o que devuelva la consulta inicial:

Ahora en nuestra área de trabajo, arrastramos un objeto EXECUTE SQL TASK donde lo configuraremos de la siguiente manera: En la opción General seleccionamos Full Result Set, en Connection Type escogemos el tipo de conexión que hayamos creado en este caso ADO.NET y en Connection el nombre de nuestra conexión y SQLStatement introducimos nuestro query en este caso SELECT cve, nombreTabla FROM dbo.catTablas

En la opción de la izquierda en Result Name escribimos 0 y en Variable Name elegimos el nombre de nuestra variable donde almacenaremos el resultado de la consulta en este caso User::resultSet


A continuación, arrastramos un objeto Foreach Loop Container y unimos el flujo desde el previo Execute SQL Task, damos doble click y en la opción Collection, en la propiedad Enumerator seleccionamos Foreach ADO Enumerator, después en ADO object source variable seleccionamos nuestra variable de tipo object y además seleccionamos Rows in the first table como la siguiente imagen:

Nos vamos a la opción Variable Mappings de nuestro Foreach Loop Container y agregaremos nuestras variables que almacenaran el contenido de las columnas de nuestra consulta contenida en la variable User::resultSet, para el ejemplo son User::cve y User::nombreTabla, además es necesario especificar el orden en el que aparecen en la consulta empezando con 0 como el inicial, veamos la imagen:

Hemos terminado con este control, damos aceptar y vamos ahora a la ventana propiedades de la variable strSQL, para poder verla basta presionar F4 o click en el menú VIEW -> Properties Window, en la expresión debemos agregar nuestra consulta que deseamos en este caso realizaré un UPDATE, damos click en el botón con los 3 puntos decimales en la propiedad Expression de la variable y nos aparecerá el Expression Builder y escribiremos nuestra consulta:

Ahora ya tenemos nuestra consulta para actualizar el contenido de las tablas, generada a partir de otra tabla que contiene los nombres de dichas tablas a modificar, solo falta ejecutar la cadena SQL con un Execute SQL Task, configuremoslo de la siguiente manera: Propiedad ResultSet -> None, SQLSourceType -> Variable, SourceVariable -> User::strSQL, y las propiedades de nuestra conexión.

Nuestro paquete quedaría más o menos así:
Solo hace falta ejecutarlo y vean el resultado.

Si tienen alguna duda al respecto, no olviden que existe la parte de los comentarios o el formulario de contacto, les responderé tan pronto me sea posible.

SALUDOS