This is a discussion on How pass column to udf in join within the SQL Server forums, part of the Microsoft SQL Server category; --> Group, Passing inline values to a udf is straightforward. However, how or is it possible to pass a column ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Group, Passing inline values to a udf is straightforward. However, how or is it possible to pass a column from the select of one table into a udf that returns a table variable in a join to the original table. The goal is to explode the number of rows in the result set out based on the result of the udf. Although the example I am providing here is simplified, we are trying to parse out multiple values out of a text column and using a select into so the result will be one row for each of row in the original table compounded by the number of occurrences in the text field. (I know bad table design but that's out of my control) Thanks, Ray create table TableOne ( Col1 int, Col2 char(5) ) go insert TableOne values (1, 'One') insert TableOne values (2, 'Two') insert TableOne values (3, 'Three') go Create Function dbo.udfTableTwo (@Id int) RETURNS @tbl TABLE (TID int, TChar char(1)) AS BEGIN Declare @test int set @test = @Id While @test >= 0 Begin INSERT @tbl VALUES (@Id, Char(65+@test)) set @test = @test - 1 End RETURN END --works select a.*, b.* from TableOne a join dbo.udfTableTwo(2) b on a.col1=b.TID --Fails with Line 1: Incorrect syntax near '.'. select a.*, b.* from TableOne a join dbo.udfTableTwo(a.col1) b on a.col1=b.TID drop table TableOne go drop function dbo.udfTableTwo go |
| |||
| SQL Server Books Online states: Parameters can take the place only of constants; they cannot be used in place of table names, column names, or the names of other database objects. This seems strikingly applicable for inline table valued UDFs. -- Anith |
| |||
| Anith, It seems to me that this statement from BOL is in regards to parameters as they are used inside the function. In the example, I am not doing such. Perhaps I'm clinging to hope but it isn't sounding like the answer has been found. When dealing with hundreds of millions of rows in an ETL process, I really like to avoid reading a table twice or using cursors. All insights are appreciated. Ray "Anith Sen" <anith@bizdatasolutions.com> wrote in message news:LfcQd.383$kU3.68@newsread1.news.pas.earthlink .net... > SQL Server Books Online states: > Parameters can take the place only of constants; they cannot be used in > place of table names, column names, or the names of other database > objects. > > This seems strikingly applicable for inline table valued UDFs. > > -- > Anith > |
| |||
| On Tue, 15 Feb 2005 00:39:12 GMT, Ray wrote: >Passing inline values to a udf is straightforward. However, how or is it >possible to pass a column from the select of one table into a udf that >returns a table variable in a join to the original table. Hi Ray, This is not possible. Your code is in fact not trying to join TableOne to one other table, but to a table of tables (since dbo.udfTableTwo would have a different content for each row in TableOne). To me, it makes sense that this won't work. It seems logical that the table has to be materialized before it can be joined to another table, but you can't materialize the udfTableTwo table without knowing the values of TableOne.col1. Best, Hugo -- (Remove _NO_ and _SPAM_ to get my e-mail address) |
| |||
| You can't reference a column from another table as a parameter to a table-valued UDF. This makes perfect sense when you consider that, in theory, the server has to be able to materialize the derived tables after the FROM clause before performing the join. The same principle also prevents you referencing columns from other tables in a derived table query. The syntax is extended in SQL Server 2005 with the CROSS APPLY operator to allow this type of correlated query but in 2000 it isn't supported. A multi-statement TVF seems unlikely to be the most efficient solution for you. How about just creating TableTwo and using it in a join: CREATE TableTwo (tid INTEGER PRIMARY KEY, tchar CHAR(1) NOT NULL UNIQUE) SELECT A.*, B.* FROM TableOne AS A, TableTwo AS B WHERE A.col1 <= B.tid -- David Portas SQL Server MVP -- |
| ||||
| Ray (someone@nowhere.com) writes: > --Fails with Line 1: Incorrect syntax near '.'. > select a.*, b.* from TableOne a join dbo.udfTableTwo(a.col1) b > on a.col1=b.TID As Aniht, Hugo and David have pointed out, there is no way you can do this in SQL 2000. However, in SQL 2005, currently in beta, you can do this: select a.*, b.* from TableOne a cross apply dbo.udfTableTwo(a.Col1) b I have not really dug into the details of the APPLY operator, so I cannot say whether this would give you expected output in your case, but this is what I get from your sample: Col1 Col2 TID TChar ----------- ----- ----------- ----- 1 One 1 B 1 One 1 A 2 Two 2 C 2 Two 2 B 2 Two 2 A 3 Three 3 D 3 Three 3 C 3 Three 3 B 3 Three 3 A (9 row(s) affected) -- Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se Books Online for SQL Server SP3 at http://www.microsoft.com/sql/techinf...2000/books.asp |