SQL Server 2005 join a number of tables in a view when some may not exist - sql

I need to create a view, however the data is generated from an application with its own db management for tables which based on column count can create over 7 SQL Server tables for one internal table definition.
The tables all end with ['m' & number], eg devicem1, devicem2 ... devicem10
They all contain logical_name as their primary key, but you can never rely on which table will hold any other column in the internal table!
I need to create a view that joins the tables together as just device so when the application changes it doesn't mess up any stored procs I want to create.
Based on this query:
CREATE VIEW device AS
SELECT *
FROM devicem1 m1, devicem2 m2, devicem3 m3, ... devicem10 m10
WHERE m1.logical_name = m2.logical_name
AND m1.logical_name = m3.logical_name
...
AND m1.logical_name = m10.logical_name
Is there some way to join ten tables where I can ignore the fact that devicem9 & devicem10 may not exist?

With regards to the requirements of a view. The tables referenced MUST exist when the view is created. The SQL engine isn't going to allow you to create a view referencing tables that don't exist.
Considering that a view is just a stored select statement, after it's created the tables can be deleted (as long as schema-binding isn't in play); however any time you call or use the view all referenced tables must exist or it will toss an error.
Also, you CAN change the schema of referenced tables as long as it doesn't remove any fields specifically used in the view but again, if a specific column used by the view is missing any query using the view will fail.
You might have more luck getting away with what your trying to do with some creative table valued functions and dynamic sql. A table valued function is basically just a view that allows parameters and extended logic.
All in all, I would say what your describing sounds a little sketchy though.

I would periodically recreate the view based on the tables that are available.
So, if the application runs every night to create the tables, then after the app runs, check which tables are available and recreate the views.
In the end, you will have to use dynamic sql, doing something like:
declare #sql varchar(max);
select #sql = (select '(select * from '+table_name+') union all'
from information_schema.tables
for xml path (''));
set #sql = left(#sql, len(#sql) - 10);
set #sql = 'create view <whatever> as '+#sql;
exec(#sql);

Related

SQL - adding new column withouth effecting existing scripts

We have a table on the SQL Server 2008 which gets populated by various stored procedures. The problem is that the authors of these stored procedures used some poor choice in code and populated this table using the following syntax:
INSERT INTO persistant_table
SELECT *
FROM #temp_table_with_data
Basically they would create a #temp_table_with_data in the script and the columns would be in the same order and with the same name as they are in the persistant_table.
Now I need to add another column to this persistant_table, but if I do that, I will break all the stored procedures.
Is there a way for me to add a column to this table without breaking all the stored procedures? (In the long run, we will change the stored procedures).
Thank you
No I think.select * will pick all columns and column number should match.
I don't think it's big effort to change the line to have particular columns only or select statement to have default value for column or null and then * to store into columns sequentially. But at least 1 line to be changed
The "ALTER TABLE" is a SQL statement that allows you to make datatype changes to a database table (i.e. change datatype as well as Size columns from an existing table).
ALTER TABLE TableName ALTER COLUMN ColumnName NVARCHAR(200)
You cannot do it without affecting old scripts. This is why 'SELECT *' is not good practice. You'd better create new scripts with explicit column names like
SELECT column1, column2 ....

Using table variables in Oracle Stored Procedure

I have lots of experience with T-SQL (MS SQL Server).
There it is quite common to first select some set of records into a
table variable or say temp table t, and then work with this t
throughout the whole SP body using it just like a regular table
(for JOINS, sub-queries, etc.).
Now I am trying the same thing in Oracle but it's a pain.
I get errors all the way and it keeps saying
that it does not recognize my table (i.e. my table variable).
Error(28,7): PL/SQL: SQL Statement ignored
Error(30,28): PL/SQL: ORA-00942: table or view does not exist
I start thinking what at all is possible to do with this
table variable and what not (in the SP body) ?
I have this declaration:
TYPE V_CAMPAIGN_TYPE IS TABLE OF V_CAMPAIGN%ROWTYPE;
tc V_CAMPAIGN_TYPE;
What on Earth can I do with this tc now in my SP?!
This is what I am trying to do in the body of the SP.
UPDATE ( SELECT t1.STATUS_ID, t2.CAMPAIGN_ID
FROM V_CAMPAIGN t1
INNER JOIN tc t2 ON t1.CAMPAIGN_ID = t2.CAMPAIGN_ID
) z
SET z.STATUS_ID = 4;
V_CAMPAIGN is a DB view, tc is my table variable
Presumably you are trying to update a subset of the V_CAMPAIGN records.
While in SQLServer it may be useful to define a 'temporary' table containing the subset and then operate on that it isn't necessary in Oracle.
Simply update the table with the where clause you would have used to define the temp table.
E.g.
UPDATE v_campaign z
SET z.status_id = 4
WHERE z.column_name = 'a value'
AND z.status <> 4
I assume that the technique you are familiar with is to minimise the effect of read locks that are taken while selecting the data.
Oracle uses a different locking strategy so the technique is mostly unnecessary.
Echoing a comment above - tell us what you want to achieve in Oracle and you will get suggestions for the best way forward.

Find out all useful columns in a table in sql server

I have a table which has 50+ columns but only few columns are getting used. that means when any stored procedure uses that table it only refers 4-5 columns in select/where statements . rest of columns are not getting used . i just want to list down those columns that are actually getting used. one way is finding out the dependencies of a table and then go through every SP and find out which columns are getting used . but in that case i have around 30+ Sp. is there any efficient way to do it.
To use multiple columns in a procedure, you can use a code like below
create procedure sp_sample
#column_names varchar(200)
as
if #column_names='' or #column_nams is null
set #column_names='*'
exec ('select '+#column_name +' from table')
Here are some examples :
exec sp_sample #columnname='id,name'
or
exec sp_sample #columnname='id,name,telphone'
Try this:
select name from syscomments c
join sysobjects o on c.id = o.id
where TEXT like '%table_name%' and TEXT like '%column_name%'
In table_name give you table name, in column_name give the column for which you want to chck the procedure dependencies.You will get the stored procedure names as output
If you import your database as a database project using the SQL Server Data Tools, you will be able to find all references to a table or column using the "Find All References" context command. What makes this particularly useful is the accuracy: it will even find instances of SELECT * that don't mention the column explicitly, but implicitly refer to it anyway. It will also not be confused by tables or columns with similar names (finding particular instances of ID is otherwise rather problematic).
If all you want to know if a column is referenced at all, you can simply delete it and see if any "unresolved reference" errors appear in the error list -- if yes, then the column is used somewhere.

Altering the Data Type of Table and View

I am having a big database with lots of view and tables.
now in many tables and views the datatype of column , named 'Company' is INT
with time the data changed and now we want 'Company' column to hold character value.
Can I write a cursor to change the datatype of all this tables and Views, Because manually changing the datatype is time consuming.
I tried modifying datatype with the help of this link: How to Change All Sql Columns of One DataType into Another
But this is working only for table , I am not able to change the datatype of Views
Thanks in advance for your help!
If you do not see the correct data type in your views, then you need to recompile them. SQL Server is not very smart about invalidating views if dependent objects change. E.g. if you have a view that select * (which you anyways should not do) from a table and you add a column, the view will not reflect the new column until you recompile it. The same is true for other changes to dependent objects.
To recompile the view use the stored procedure sp_refreshview. This MSDN page describes the procedure and also has a script at the bottom of the page that allows you to bulk refresh all your views.
First of all, you don't need to modify anything in view. Any change in corresponding table will automatically reflect in your view.
If not, it might be because if a view is not created with schemabinding, sp_refreshview should be run when changes are made to the objects underlying the view that affect the definition of the view. Otherwise, the view might produce unexpected results when it is queried. SO as suggested by #Ralf, I +1 that answer, use sp_refreshview to update view.
For your comment ALTER TABLE ALTER COLUMN Company failed because one or more objects access this column. This is because some constraint or index is using that column you have to first drop that and then only you might be able to alter that column.
You can find related constraint using query:
select db_name() as CONSTRAINT_CATALOG
,t_obj.name as TABLE_NAME
,user_name(c_obj.uid) as CONSTRAINT_SCHEMA
,c_obj.name as CONSTRAINT_NAME
,col.name as COLUMN_NAME
,col.colid as ORDINAL_POSITION
,com.text as DEFAULT_CLAUSE
from sysobjects c_obj
join syscomments com on c_obj.id = com.id
join sysobjects t_obj on c_obj.parent_obj = t_obj.id
join sysconstraints con on c_obj.id = con.constid
join syscolumns col on t_obj.id = col.id
and con.colid = col.colid
where
c_obj.uid = user_id()
Drop any index and/or constraint on column & then try alter, it must work then.
Also refer answers to this question Drop a column from table problem (SQL Server 2008)
Hope it helps.

SQL: how to find a mapping of view columns to table columns?

In Microsoft SQL Server 2008 R2, let's say my database has the following view:
create view [dbo].[MyView]
(
[MyColumnA]
)
AS
(SELECT MyColumnB FROM MyTable)
Now let's suppose I only know that there is a view called MyView that has a column called MyColumnA, but I don't know that it maps to MyTable.ColumnB. What is the easiest/fastest way to determine which table and column MyView.ColumnA maps to? Is there a query that can tell me this? Something like:
SELECT TABLE_NAME, TABLE_COLUMN_NAME
FROM INFORMATION_SCHEMA.VIEW_MAPPINGS
WHERE VIEW_NAME = 'MyView' AND VIEW_COLUMN_NAME = 'MyColumnA'
This query would return [MyTable, MyColumnB].
Currently I have to find the view in SSMS Object Explorer, right click it and generate the create script, then search for the name of the view's column. Then I note which ordinal position it is in the view (let's say 4th column), and have to find the corresponding 4th column in the select statement. The select statement will most likely be using a table alias, so then I have to look through the JOIN statements to find the table name based on the alias.
This is quite time consuming, and I'm hoping to find a faster way, if not by a query then perhaps by some other process that is faster or easier than mine.
SP_DEPENDS should work
SP_DEPENDS 'MyView'