使用表变量返回表值函数

时间:2015-06-16 09:33:26

标签: sql-server tsql

我有一张来自软件提供商的表格,该表格一直未经考虑用于其目的。

他们决定在表格中列出5起事故,而不是在行中显示事故。

我已经编写了一个查询来逐行整理这些查询表'表'我希望把它写成一个表值函数,但我似乎不断得到错误。

我正在使用表变量插入,因为我已经读过你不能使用临时表。

查询返回我想要的数据,但我想在表值函数中返回数据。

我目前的代码:

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

更新

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;

我用

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

得到:

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

2 个答案:

答案 0 :(得分:2)

对于我的生活,我不明白为什么你想要一个表值函数。既然你说你的问题是你不能使用临时表,你可以使用公用表表达式。

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;

也许你的意思是存储过程而不是表值函数。以下是您创建程序的方法:

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

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

在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() 

答案 1 :(得分:0)

我想你想要这个:

 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()

根据返回字段的顺序使用索引值,以及Get中的类型。

并阅读:https://www.simple-talk.com/dotnet/.net-framework/using-table-valued-parameters-with-vb.net/

这将对您有所帮助:https://msdn.microsoft.com/en-us/library/bb386954%28v=vs.110%29.aspx