| Author |
Topic |
|
mattt
Posting Yak Master
194 Posts |
Posted - 2011-03-10 : 07:11:32
|
Hi,I've got a short t-sql script that creates a cursor on a table and runs through all the rows, performing some basic maintenance. The database always runs against the database "dbname" which can have multiple schemas, but each schema will always have a table of name "tablename". It's this table I want to run my script against. The database name and the tablename are fixed remember, but "schemaname" is variable: Declare c1 cursor read_onlyForSelect intRowId from [dbname].[schemaname].[tablename]Declare @trackingID intOpen c1Fetch next from c1 into @trackingIDWhile @@fetch_status = 0Begin-- do stuff Fetch next from c1 into @trackingIDEndClose c1Deallocate c1 Is there a way of iterating through all the schemas, making sure that the select statement to create the cursor uses the right schema name for the current schema and running the cursor contents against "tablename" in that schema?Cheers,Matt |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2011-03-10 : 07:58:57
|
| Ok, I need to say first that this sounds like a really horrible idea. It would be really interesting to see the "-- do stuff" part...But you can get the schema name by doing a SELECT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'tablename'- LumbagoMy blog-> http://thefirstsql.com/2011/02/07/regular-expressions-advanced-string-matching-and-new-split-function-sql-server-2008-r2/ |
 |
|
|
mattt
Posting Yak Master
194 Posts |
Posted - 2011-03-10 : 08:06:17
|
quote: Originally posted by Lumbago Ok, I need to say first that this sounds like a really horrible idea. It would be really interesting to see the "-- do stuff" part...But you can get the schema name by doing a SELECT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'tablename'
Thanks, will check it out. Not immediately obvious to me how I can use that data in my query without restoring to dynamic SQL?In the meantime the "to do" is quite simple. It references an xml field for the row and looks for a certain key. If that key has a value, it inserts it into a different field in the same row. It's for speed of processing later down the line - better to do it upfront when the data is loaded instead of trying to pull out that value each and every time we need to use it. |
 |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2011-03-10 : 08:24:55
|
| It's not possible to query a dynamic range of tables without using dynamic sql (there is the sp_msforeachtable-procedure but that would not be suitable I think).But why are you doing this "do stuff" in a cursor loop? Set based is always a lot better and a lot more efficient...- LumbagoMy blog-> http://thefirstsql.com/2011/02/07/regular-expressions-advanced-string-matching-and-new-split-function-sql-server-2008-r2/ |
 |
|
|
mattt
Posting Yak Master
194 Posts |
Posted - 2011-03-10 : 08:35:01
|
quote: Originally posted by Lumbago But why are you doing this "do stuff" in a cursor loop? Set based is always a lot better and a lot more efficient...
The answer is probably "ignorance". Care to point me at some suitable information? |
 |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2011-03-10 : 08:47:12
|
| Well, you can always google "set based vs cursor". But if you want specific advice you'll need to show us what you're doing. If the "do stuff" is business sensitive, try to illustrate the problem using different table/column names etc.- LumbagoMy blog-> http://thefirstsql.com/2011/02/07/regular-expressions-advanced-string-matching-and-new-split-function-sql-server-2008-r2/ |
 |
|
|
mattt
Posting Yak Master
194 Posts |
Posted - 2011-03-10 : 08:58:27
|
quote: Originally posted by Lumbago Well, you can always google "set based vs cursor". But if you want specific advice you'll need to show us what you're doing. If the "do stuff" is business sensitive, try to illustrate the problem using different table/column names etc.
Your persistent assistance is much appreciated. Here's the full whack - I only left it out originally because I thought it was irrelevant:use [dbname]Declare c1 cursor read_onlyForSelect intRowId from [dbname].[schemaname].[tablename]Declare @trackingID intOpen c1Fetch next from c1 into @trackingIDWhile @@fetch_status = 0Begin if (select strGroupId from [dbname].[schemaname].[tablename] where intRowId = @trackingID) is null begin declare @groupId nvarchar(255) select @groupId = xmlSource.value(' declare default element namespace "xmlSchemaname"; (/RootNode/ChildNode[Key="soughtKeyValue"]/Value)[1]', 'nvarchar(255)') from [dbname].[schemaname].[tablename] where intRowId = @trackingID update [dbname].[schemaname].[tablename] set strGroupId = @groupId where intRowId = @trackingID end Fetch next from c1 into @trackingIDEndClose c1Deallocate c1 |
 |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2011-03-10 : 09:21:36
|
Well...I have a feeling that you have renamed at least two different tables to [dbname].[schemaname].[tablename] so it's a little hard to make something that's "plug'n'play" but I think this should be pretty close to what you need to do. I'm also not very good with this xml-stuff so you might have to do some tweaking there as well:update a set a.strGroupId = b.xmlSource.value('declare default element namespace "xmlSchemaname"; (/RootNode/ChildNode[Key="soughtKeyValue"]/Value)[1]', 'nvarchar(255)')from [dbname].[schemaname].[tablename] a inner join [dbname].[schemaname].[tablename] b on a.intRowId = b.intRowIdwhere a.strGroupId is null- LumbagoMy blog-> http://thefirstsql.com/2011/02/07/regular-expressions-advanced-string-matching-and-new-split-function-sql-server-2008-r2/ |
 |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2011-03-10 : 09:27:09
|
| And if you make it work for you it will do everything in one go...no need for he cursor.- LumbagoMy blog-> http://thefirstsql.com/2011/02/07/regular-expressions-advanced-string-matching-and-new-split-function-sql-server-2008-r2/ |
 |
|
|
mattt
Posting Yak Master
194 Posts |
Posted - 2011-03-10 : 09:28:48
|
| Ah but that's just it - I haven't changed two table names. This is operating on the same table. Each row has a frequently used value (groupId) that's hidden in an xml field. Accessing that value is costly because the xml is often quite large and we're looking to match a single value. So the purpose of this excercise is to do a one-time process that grabs the value and puts it in a field on its own in the same row, so that it's more readily available for use in other transactions. Hence the cursor. |
 |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2011-03-10 : 09:32:26
|
I'm sorry for the spamming of this topic, I'm just bored basically. But if this is in fact all the same table then it could be even simpler:update [dbname].[schemaname].[tablename] set strGroupId = xmlSource.value('declare default element namespace "xmlSchemaname"; (/RootNode/ChildNode[Key="soughtKeyValue"]/Value)[1]', 'nvarchar(255)')where strGroupId is null- LumbagoMy blog-> http://thefirstsql.com/2011/02/07/regular-expressions-advanced-string-matching-and-new-split-function-sql-server-2008-r2/ |
 |
|
|
|