May 30, 2006 at 1:21 am
I have a sitaution where I am trying to display an increasing number of tables in a view.
(The tables on which the view is based can be considered "count tables" based on other larger tables that can look very different except for one thing; they all have an item number field. The "count tables" have only two fields; one item number field char (17) and a count field int where I count item number grouped by item number.)
The goal is that anyone in the company can run an sp that will ALTER VIEW so it includes the latest "count table".
The VIEW is based on a gross item number list which has been left outer joined with all count tables on the item number.
That way it is possible to monitor - for each item number - how many pieces have been shipped to which customer (by an increasing number of columns).
But how does one write SQL that ALTERs a VIEW and adds an extra left outer join when a user executes an sp (including input parameters)?
Is it possible at all?
May 30, 2006 at 3:40 am
Your proc will need to execute some dynamic SQL - this is often frowned upon for general SQL queries (too many debates - hope it doesn't fire up here!) but is the only way to do it in your case.
Build up a string for the view's code. Then do
exec(@myStringForView)
I'm not sure I follow your database design - perhaps we can all come up with a better way if we can see some sample data and tables. You could redesign (probably not possible given it is a running system) to avoid the need to create new tables and instead store the data in one table with an extra column (which I guess would be a "table_name"/category column).
Let us know how you go
May 30, 2006 at 3:44 am
Oh, and security issues are fairly important with dynamic SQL. Any dynamic SQL is executed in the security context of the caller of the stored proc, not the owner of the stored proc. EG, you can have stored procs written by the database owner that can do things to table that you as a user have been denied the rights to do but you as a user can execute that proc and still manipulate the tables.
However, any dynamic SQL within the proc will execute using your rights & privileges, not those of the stored proc owner. So the user in SQL calling the stored proc that eventually updates the view will need the rights to alter that view.
Finally... Another way to perhaps avoid the need to recode the view would be to have an (possibly ugly) cursor adding rows to a temp table. The cursor would loop over the tables to which you plan to join and retrieve the appropriate rows. The rows are then added to the temp table. The resultset would be different - rather than
Col1, Col2, Col3, Col4
Val1, Val2, Val3, Val4
you would end up with
Name Value
Col1 Val1
Col2 Val2
Col3 Val3
....
This is probably a better way to store the data in the first place (avoids changing tables & views) - but, as always, depends on your requirements
May 30, 2006 at 3:53 am
Hi Jane,
I'm not sure I've completely understood your problem so correct me if I'm wrong.
You've got a view that looks something like this.
select
from a1
select distinct 'join ' + table_name + ' on ' + table_name + '.itemNumber =base_table.itemNumber'
from information_schema.columns c
(select * from information_schema.columns
where table_name = c.table_name
and (column_name = 'itemNumber'))
(select * from information_schema.columns
where table_name = c.table_name
and (column_name = 'itemCount'))
And once you're done, you'll need to append that to the initial part of the select statement.
Essentially you'll end up with something like this. That should be the general idea anyway.
declare @select_statement varchar(8000)
declare @join_statement varchar(500)
set @select_statement = 'select fields,... from baseTable' + char(10) + char(13)
select distinct 'join ' + table_name + ' on ' + table_name + '.itemNumber =base_table.itemNumber'
from information_schema.columns c
(select * from information_schema.columns
where table_name = c.table_name
and (column_name = 'itemNumber'))
(select * from information_schema.columns
where table_name = c.table_name
and (column_name = 'itemCount'))
fetch next from my_cursor into @join_statement
set @select_statement = @select_statement + @join_statement + char(10) + char(13)
May 30, 2006 at 3:55 am
Oh, and Ian is right about the security issues behind executing dynamic sql but it is the only way to do it in this case.
Unless you decide to change your design as Ian suggested.
Good luck
May 30, 2006 at 4:54 am
Thanks a lot for your input, you make the SQL world even more fun!
I'll try, however since I'm a beginner it might take more than 5 minutes, which is also a reason why your advise to redesign is a popular option right now .
Thanks again!
May 30, 2006 at 7:43 am
If redesign is an option, I would strongly recommend it. This sort of information should be drawn from an Orders table with a GROUP BY query, not stored in an increasing number of tables.
Don't store what you can calculate.
Viewing 7 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy