Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
sixsigma1978
Starting Member
25 Posts |
Posted - 2011-08-17 : 14:35:34
|
All - I have a script that tends to repeat there where clause over and over again and was wondering if there was some way for me to substitute the parameters of the where clause.update T1 set C1="xx" where C2 in (1, 2, 3, 4, 5);update T2 set C3="yy", C4="zz" where C2 in (1, 2, 3, 4, 5);.... As you can see the IN (1, 2, 3, 4, 5); repeats multiple times - and was wondering If I could use a DECLARE TYPE statement or something equivalent to substitute it at the beginning of the script, thus:DECLARE TYPE some_var (1,2,3,4,5);BEGINupdate T2 set C3="yy", C4="zz" where C2 in (some_var);END; IS there anything similar in SQL? |
|
|
Kristen
Test
22859 Posts |
Posted - 2011-08-17 : 15:59:51
|
| I would put the "list" 1,2,3,4,5... into a temporary table and then JOIN that to T1 and T2 to restrict the data set.That only works for your particular example using the IN statement, so may not be appropriate for more general cases.You could use dynamic SQL - that would require that the "C2" column name, in your example, was consistently use on all tables T1, T2, ...Using parameter substitution (e.g. using sp_ExecuteSQL) this would be a highly performant solution, although there would be Permissions issues which would be more complicated to solve than using a Stored Procedure and granting it EXECUTE permission. |
 |
|
|
sixsigma1978
Starting Member
25 Posts |
Posted - 2011-08-17 : 16:15:02
|
Thanks Kirsten - however, after googling (and a bit of plagiarizing :) )I found an interim solution- this seems a bit complex - but looks like the trick is in getting the parser function right!!CREATE OR REPLACE FUNCTION Split( PC$Chaine IN VARCHAR2, -- input string PN$Pos IN PLS_INTEGER, -- token number PC$Sep IN VARCHAR2 DEFAULT ',' -- separator character)RETURN VARCHAR2IS LC$Chaine VARCHAR2(32767) := PC$Sep || PC$Chaine ; LI$I PLS_INTEGER ; LI$I2 PLS_INTEGER ;BEGIN LI$I := INSTR( LC$Chaine, PC$Sep, 1, PN$Pos ) ; IF LI$I > 0 THEN LI$I2 := INSTR( LC$Chaine, PC$Sep, 1, PN$Pos + 1) ; IF LI$I2 = 0 THEN LI$I2 := LENGTH( LC$Chaine ) + 1 ; END IF ; RETURN( SUBSTR( LC$Chaine, LI$I+1, LI$I2 - LI$I-1 ) ) ; ELSE RETURN NULL ; END IF ;END;CREATE OR REPLACE FUNCTION Dynamic_In ( PC$list IN VARCHAR2 )RETURN sys.dbms_debug_vc2collIS ttab sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll() ; LC$Token VARCHAR2(100) ; i PLS_INTEGER := 1 ;BEGIN -- Populate the collection -- LOOP LC$Token := Split( PC$List, i , ',') ; EXIT WHEN LC$Token IS NULL ; ttab.extend ; ttab(ttab.COUNT) := LC$Token ; i := i + 1 ; END LOOP ; RETURN ttab ;END ;BEGINDECLARE LC$List Varchar2(100) := '1, 2, 3'; update T set C1='xx' where C2 in (SELECT * FROM TABLE( CAST ( Dynamic_In(LC$List) AS sys.dbms_debug_vc2coll ) ) );END; |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2011-08-17 : 16:34:41
|
That's for Oracle by the looks of it.If you just have an IN list then, yes, a SPLITTER function that puts the values into a temporary table (or a function representing a table) will do nicely if you are using SQL Server there was some discussion about various flavours of making a Splitter Function in this thread:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648 |
 |
|
|
sixsigma1978
Starting Member
25 Posts |
Posted - 2011-08-18 : 09:41:21
|
| Yes - that is an oracle version of the split function - I was battling to convert it to the SQL Server semantics - your link is very helpful!! thanks ! |
 |
|
|
|
|
|
|
|