Usando vistas para crear subconjuntos de datos

Usando vistas para crear subconjuntos de datos

La verdad es que he usado esta t├®cinca bastante, lo que hago es crear vistas, en una base de datos que apunten a las tablas o vistas originales en la otra base de datos. De esta forma no se duplica el espacio, y adem├ís no se penaliza (apenas) el rendimiento, en principio la ├║nica operaci├│n adicional que hace el motor frente a que est├®n en la misma base de datos es comprobar que el usuario tenga permisos en la otra base de datos. En resumen, no es malo crear una vista en una base de datos apuntando a otra en el mismo server, las operaciones CRUD (Inserci├│n, lectura, actualizaci├│n y borrado) segurian funcionando todas como si de una tabla se tratase.

Sin embargo si quieres crear un gran n├║mero de vistas, la cosa puede ser tediosa. Si s├® que por ejemplo voy a crear vistas para todas las tablas de un esquema, o para todas las que cumplen ciertos patrones, puedo utilizar otra t├®cnica que exploto de vez en cuando, crear una consulta que me devuelva las consultas a ejecutar, para despues de esto copiar y pegar.

Si las operaciones a hacer son CRUD, no hay problema separandolas con ; todo funciona perfectamente, sin embargo si las operaciones a realizar son operaciones de definici├│n de objetos (sentencias DDL), entonces hay que sepaararlas por GO para ejecutarlas en el entorno, o bien, hay que ejecutarlas una a una, esto, tampoco es algo que yo desee. ┬┐como hago para a├▒adir los GO?. Las t├®cnicas que uso habitualmente son dos una a├▒adir al final de la sentencia el caracter 13 y el caracter 10 . Algo as├¡

select 'select 1 ' +char(10) +CHAR(13) + 'go'

Sin embargo este c├│digo no funciona en el modo Grid, habitual de management estudio, si copiamos desde el grid el c├│digo y lo pegamos, nos aparecer├í en una sola l├¡nea y no en dos, que es lo que buscamo,s as├¡ pues hemos de pasara a modo texto (pulsando CTRL+to bien en el men├║ Query->Results To->Text. La verdad es que queda algo “chapuza” esta alternativa.

┬┐alguna otra soluci├│n? Pues lo que tendr├¡amos que hacer es adem├ís de construir la sentencia, a├▒adir tantos “GO” como sentencias haya… eso es sencillo, si la primera linea es :

select  'CREATE VIEW ' + TABLE_SCHEMA+'.['+TABLE_NAME  +  '] AS select * from vdnav60.'+table_schema+'.['+table_name+'];'  from information_Schema.tables where table_name like '%patron%'

Lo que hemos de hacer es un select, pero esta vez solo con el literal “GO” del mismo origen, de esta forma tendremos el mismo n├║mero de “go”. Ser├¡a algo as├¡

select  'GO'  from information_Schema.tables where table_name like '%patron%'

El problema aquí viene por dos partes, la primera, las dos sentencias no son una sola, que es lo que yo necesito, (sin embargo ambas solo devuelven una columna, que es un literal con lo que sirve como código). Esto podemos solucionarlo usando una cláusula UNION ALL (al ser la estrutura devuelta igual).

Pero esto aún encierra un problema adicional, que es que no vienen en el orden adecuado, para ordenar algo podemos usar la cláusula order by, pero no tenemos ningún campo que nos sirva para hacer ese entrelazado (o al menos no podemos suponer que lo tenemos), es por ello que yo uso este otro script.

select  'CREATE VIEW ' + TABLE_SCHEMA+'.['+TABLE_NAME  +  '] AS select * from vdnav60.'+table_schema+'.['+table_name+'];'  from information_Schema.tables where table_name like '%patron%'
union all
select row_number() over( order by table_name), 'go' from vdnav60.information_Schema.tables where table_name like '%patron%'

Las cláusulas Row_number() nos van a devolver el número de fila según los criterios que usemos (partition by y order by), y luego como las dos tablas debieran devolver lo mismo, el resultado es que ordenando por ese número de fila, obtendremos la consulta perfectamente compuesta , como puede verse en la imagen

Disfrutad el c├│digo

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *