简体   繁体   中英

Returning Table Valued Function with Table Variable

I have a table from a software provider that has been poorly thought out for the purpose its used for.

Instead of displaying accidents in rows they have decided to include 5 accidents as a column in the table.

I have written a query to collate these into a row by row 'table' I wish to write this as a Table-Valued Function though and I seem to get an error constantly.

I am using a table variable to insert into as I've read you can't use temporary tables.

The query returns the data how I want it to but I want to return the data in a table valued function.

My code at present:

DECLARE @Accidents TABLE( B@ int, PolRef@ VARCHAR(10), [Code1] VARCHAR(4),[Date1] DATETIME, [Fine1] VARCHAR(10), [Driver1] VARCHAR(20), [Code2] VARCHAR(4),[Date2] DATETIME, [Fine2] VARCHAR(20), [Driver2] VARCHAR(20),[Code3] VARCHAR(4),[Date3] DATETIME, [Fine3] VARCHAR(30), [Driver3] VARCHAR(20),[Code4] VARCHAR(4),[Date4] DATETIME, [Fine4] VARCHAR(40), [Driver4] VARCHAR(20),[Code5] VARCHAR(4),[Date5] DATETIME, [Fine5] VARCHAR(50), [Driver5] VARCHAR(20))
DECLARE @Branch INT, @PolRef NVARCHAR(10)

SET @Branch = 0
SET @Polref = 'AMCX06PC01'

INSERT INTO @Accidents
SELECT [B@], [PolRef@], CONVERT(VARCHAR(2),[Conv_code1]) + CONVERT(VARCHAR(2),[Conv_code_nn1]) AS [Code1],[Conv_date1] AS [Date1], [Conv_fine1] AS [Fine1], [Conv_driver1] AS [Driver1] ,
CONVERT(VARCHAR(2),[Conv_code2]) + CONVERT(VARCHAR(2),[Conv_code_nn2]) AS [Code2],[Conv_date2] AS [Date2], [Conv_fine2] AS [Fine2], [Conv_driver2] AS [Driver2] ,
CONVERT(VARCHAR(2),[Conv_code3]) + CONVERT(VARCHAR(2),[Conv_code_nn3]) AS [Code3],[Conv_date3] AS [Date3], [Conv_fine3] AS [Fine3], [Conv_driver3] AS [Driver3] ,
CONVERT(VARCHAR(2),[Conv_code4]) + CONVERT(VARCHAR(2),[Conv_code_nn4]) AS [Code4],[Conv_date4] AS [Date4], [Conv_fine4] AS [Fine4], [Conv_driver4] AS [Driver4] ,
CONVERT(VARCHAR(2),[Conv_code5]) + CONVERT(VARCHAR(2),[Conv_code_nn5]) AS [Code5],[Conv_date5] AS [Date5], [Conv_fine5] AS [Fine5], [Conv_driver5] AS [Driver5] 
FROM [dbo].[ic_BD_AX] AS ax
WHERE [B@] = @Branch AND [PolRef@] = @PolRef

SELECT * FROM 
(
SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code1] AS [Code], [Date1] AS [Date], [Fine1] AS [Fine], [Driver1] AS [Driver] FROM @Accidents WHERE [PolRef@] = @Polref AND [B@] = @branch
UNION ALL
SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code2] AS [Code], [Date2] AS [Date], [Fine2] AS [Fine], [Driver2] AS [Driver] FROM @Accidents WHERE [PolRef@] = @Polref AND [B@] = @branch
UNION ALL
SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code3] AS [Code], [Date3] AS [Date], [Fine3] AS [Fine], [Driver3] AS [Driver] FROM @Accidents WHERE [PolRef@] = @Polref AND [B@] = @branch
UNION ALL
SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code4] AS [Code], [Date4] AS [Date], [Fine4] AS [Fine], [Driver4] AS [Driver] FROM @Accidents WHERE [PolRef@] = @Polref AND [B@] = @branch
UNION ALL
SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code1] AS [Code], [Date1] AS [Date], [Fine1] AS [Fine], [Driver1] AS [Driver] FROM @Accidents WHERE [PolRef@] = @Polref AND [B@] = @branch
) AS MyTbl
WHERE [Code] IS NOT NULL

UPDATE

ALTER PROCEDURE GetAccidents
  @Branch int,
  @Polref varchar(50)
AS 

WITH accident_cte AS (
SELECT [B@], [PolRef@], CONVERT(VARCHAR(2),[Conv_code1]) + CONVERT(VARCHAR(2),[Conv_code_nn1]) AS [Code1],[Conv_date1] AS [Date1], [Conv_fine1] AS [Fine1], [Conv_driver1] AS [Driver1] ,
  CONVERT(VARCHAR(2),[Conv_code2]) + CONVERT(VARCHAR(2),[Conv_code_nn2]) AS [Code2],[Conv_date2] AS [Date2], [Conv_fine2] AS [Fine2], [Conv_driver2] AS [Driver2] ,
  CONVERT(VARCHAR(2),[Conv_code3]) + CONVERT(VARCHAR(2),[Conv_code_nn3]) AS [Code3],[Conv_date3] AS [Date3], [Conv_fine3] AS [Fine3], [Conv_driver3] AS [Driver3] ,
  CONVERT(VARCHAR(2),[Conv_code4]) + CONVERT(VARCHAR(2),[Conv_code_nn4]) AS [Code4],[Conv_date4] AS [Date4], [Conv_fine4] AS [Fine4], [Conv_driver4] AS [Driver4] ,
  CONVERT(VARCHAR(2),[Conv_code5]) + CONVERT(VARCHAR(2),[Conv_code_nn5]) AS [Code5],[Conv_date5] AS [Date5], [Conv_fine5] AS [Fine5], [Conv_driver5] AS [Driver5] 
  FROM [dbo].[ic_BD_AX] AS ax
  WHERE [B@] = @Branch AND [PolRef@] = @PolRef
  )

SELECT * FROM 
(
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code1] AS [Code], [Date1] AS [Date], [Fine1] AS [Fine], [Driver1] AS [Driver] FROM accidents_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
  UNION ALL
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code2] AS [Code], [Date2] AS [Date], [Fine2] AS [Fine], [Driver2] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
  UNION ALL
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code3] AS [Code], [Date3] AS [Date], [Fine3] AS [Fine], [Driver3] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
  UNION ALL
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code4] AS [Code], [Date4] AS [Date], [Fine4] AS [Fine], [Driver4] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
  UNION ALL
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code1] AS [Code], [Date1] AS [Date], [Fine1] AS [Fine], [Driver1] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
) AS MyTbl
WHERE [Code] IS NOT NULL;

I call this with

EXEC [dbo].[GetAccidents] @Branch = 0 , -- int
@Polref = 'AMCX06PC01' -- varchar(50)

And get:

Msg 208, Level 16, State 1, Procedure GetAccidents, Line 6
Invalid object name 'accidents_cte'.

For the life of me I can't see why you want a table valued function. Since you say your problem is that you can't use temp tables, you can use a common table expression instead.

SET @Branch = 0;
SET @Polref = 'AMCX06PC01'; -- you need semicolon before cte

WITH accident_cte AS (
  SELECT [B@], [PolRef@], CONVERT(VARCHAR(2),[Conv_code1]) + CONVERT(VARCHAR(2),[Conv_code_nn1]) AS [Code1],[Conv_date1] AS [Date1], [Conv_fine1] AS [Fine1], [Conv_driver1] AS [Driver1] ,
  CONVERT(VARCHAR(2),[Conv_code2]) + CONVERT(VARCHAR(2),[Conv_code_nn2]) AS [Code2],[Conv_date2] AS [Date2], [Conv_fine2] AS [Fine2], [Conv_driver2] AS [Driver2] ,
  CONVERT(VARCHAR(2),[Conv_code3]) + CONVERT(VARCHAR(2),[Conv_code_nn3]) AS [Code3],[Conv_date3] AS [Date3], [Conv_fine3] AS [Fine3], [Conv_driver3] AS [Driver3] ,
  CONVERT(VARCHAR(2),[Conv_code4]) + CONVERT(VARCHAR(2),[Conv_code_nn4]) AS [Code4],[Conv_date4] AS [Date4], [Conv_fine4] AS [Fine4], [Conv_driver4] AS [Driver4] ,
  CONVERT(VARCHAR(2),[Conv_code5]) + CONVERT(VARCHAR(2),[Conv_code_nn5]) AS [Code5],[Conv_date5] AS [Date5], [Conv_fine5] AS [Fine5], [Conv_driver5] AS [Driver5] 
  FROM [dbo].[ic_BD_AX] AS ax
  WHERE [B@] = @Branch AND [PolRef@] = @PolRef

SELECT * FROM 
(
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code1] AS [Code], [Date1] AS [Date], [Fine1] AS [Fine], [Driver1] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
  UNION ALL
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code2] AS [Code], [Date2] AS [Date], [Fine2] AS [Fine], [Driver2] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
  UNION ALL
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code3] AS [Code], [Date3] AS [Date], [Fine3] AS [Fine], [Driver3] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
  UNION ALL
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code4] AS [Code], [Date4] AS [Date], [Fine4] AS [Fine], [Driver4] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
  UNION ALL
  SELECT @Branch AS [Branch], @PolRef AS [Polref],[Code1] AS [Code], [Date1] AS [Date], [Fine1] AS [Fine], [Driver1] AS [Driver] FROM accident_cte WHERE [PolRef@] = @Polref AND [B@] = @branch
) AS MyTbl
WHERE [Code] IS NOT NULL;

Maybe you mean stored procedure instead of table value function. Below is how you'd create the procedure:

CREATE PROCEDURE GetAccidents
  @Branch int,
  @Polref varchar(50)
AS 

WITH accident_cte AS (
/* ... rest of query from above ... */

To execute the procedure in VB.Net:

Dim cmd as new sqlCommand("GetAccidents")
cmd.CommandType = CommandType.StoredProcedure
cmd.Connection = 'your sql connection
cmd.Parameters.AddWithValue("branch", 0)
cmd.Parameters.AddWithValue("Polref", "AMCX06PC01")
Dim reader As SqlDataReader = cmd.ExecuteReader() 

I think you want this:

 Dim reader As SqlDataReader= cmd.ExecuteReader
 Dim MyList as new List(Of WhateverObject)
 Do While reader.Read
     Dim obj as new WhateverObj
     obj.Property1 = Reader.GetInt32(0)
     obj.Property2 = Reader.GetString(1)
     MyList.add(obj)
 Loop
 reader.Close()
 cmd.Dispose()

Where you use the index value based on the order of the returned fields, and its type in the Get.

and also read : https://www.simple-talk.com/dotnet/.net-framework/using-table-valued-parameters-with-vb.net/

and this will help you : https://msdn.microsoft.com/en-us/library/bb386954%28v=vs.110%29.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM