SQL将CSV文本转换为表格

时间:2016-06-17 21:30:11

标签: sql sql-server tsql csv

我有一个包含客户订单列表的表(s84_Schedule)。我有第二个表,对订单有评论(s84_ScheduleNotes)。当我从s84_Schedule中提取订单列表时,我会执行左外连接以获取s84_ScheduleNotes的最新评论,因为并不总是对每个订单都有评论。

问题:我还有一个SQL函数,它将逗号分隔的ProductID列表转换为临时表;这个功能似乎没有正常工作。我不明白这些是如何相关的,但是......如果我只使用一个产品ID(意思是,ProductVal变量中没有逗号),则左外连接永远不会从s84_ScheduleNotes中提取最新的注释。但是,如果我在ProductVal中提供以逗号分隔的2个ProductID,则会显示最新的评论。

以下是将CSV转换为临时表的代码(很久以前在某个地方偷了这个)...

CREATE FUNCTION [dbo].[CSVToTable] (@InStr VARCHAR(MAX))
RETURNS @TempTab TABLE
   (id int not null)
AS
BEGIN
    ;-- Ensure input ends with comma
    SET @InStr = REPLACE(@InStr + ',', ',,', ',')
    DECLARE @SP INT
DECLARE @VALUE VARCHAR(1000)
WHILE PATINDEX('%,%', @INSTR ) <> 0 
BEGIN
   SELECT  @SP = PATINDEX('%,%',@INSTR)
   SELECT  @VALUE = LEFT(@INSTR , @SP - 1)
   SELECT  @INSTR = STUFF(@INSTR, 1, @SP, '')
   INSERT INTO @TempTab(id) VALUES (@VALUE)
END
    RETURN
END
GO

这是我的程序,它提取订单和评论......

CREATE PROCEDURE dbo.GetFilteredSchedule
(
  @InstallDateOperator INT,
  @InstallDateRange1 DATETIME,
  @InstallDateRange2 DATETIME,
  @InstallDateDynRange1 INT,
  @InstallDateDynRange2 INT,

  @CustExpectedOperator INT,
  @CustExpectedRange1 DATETIME,
  @CustExpectedRange2 DATETIME,
  @CustExpectedDynRange1 INT,
  @CustExpectedDynRange2 INT,

  @CompletedDateOperator INT,
  @CompletedDateRange1 DATETIME,
  @CompletedDateRange2 DATETIME,
  @CompletedDateDynRange1 INT,
  @CompletedDateDynRange2 INT,

  @ProdInStoreDateOperator INT,
  @ProdInStoreDateRange1 DATETIME,
  @ProdInStoreDateRange2 DATETIME,
  @ProdInStoreDateDynRange1 INT,
  @ProdInStoreDateDynRange2 INT,

  @InvoiceNumVal VARCHAR(2000),
  @InstallerVal VARCHAR(2000),
  @CustomerVal VARCHAR(2000),
  @SubdivisionVal VARCHAR(2000),
  @ProductVal VARCHAR(2000),
  @LotNumVal VARCHAR(2000),
  @EstimateNumVal VARCHAR(2000),
  @SONumVal VARCHAR(2000),
  @ProdInStoreVal BIT,
  @OrderProcessedVal BIT,
  @StatusVal VARCHAR(2000),
  @FieldRepVal VARCHAR(2000),
  @WorkOrderNumVal VARCHAR(2000),
  @WindowVal VARCHAR(2000),
  @StoreVal VARCHAR(2000),
  @DriverVal VARCHAR(2000),
  @YardEmployeeVal VARCHAR(2000),
  @TruckTypeVal VARCHAR(2000),

  @LotNumExact INT,
  @StatusIDExact INT,
  @SearchText VARCHAR(2000),

  @CustomerIdRestriction VARCHAR(2000),

  @OrderBy1 INT,
  @OrderBy2 INT
)
AS
BEGIN
    SELECT sch.ScheduleID, sch.InstallDate, sch.CustomerExpectedDate, sch.CompletedDate, sch.InvoiceNumber,
           sch.InstallerID, sch.CustomerID, sch.SubdivisionID, sch.ProductID, sch.LotNumber, sch.EstimateNumber, sch.SONumber,
           sch.ProductInStore, sch.ProductInStoreDate, sch.OrderProcessed, sch.HomeownerInfo, sch.StatusID, sch.FieldRepID,
           sch.WindowID, sch.StoreID, sch.ConnectedToProject, sch.DriverEmailAddress, sch.YardEmployeeEmailAddress, sch.TruckTypeID,
           installer.InstallerName AS 'InstallerName',
           customer.CustomerName AS 'CustomerName',
           subdivision.SubdivisionName AS 'SubdivisionName',
           product.ProductName AS 'ProductName',
           fieldRep.FieldRepName AS 'FieldRepName',
           window.WindowName AS 'WindowName',
           store.StoreName AS 'StoreName',
           stat.StatusName AS 'StatusName',
           driver.LastName AS 'DriverLastName', driver.FirstName AS 'DriverFirstName',
           yardEmployee.LastName AS 'YardEmployeeLastName', yardEmployee.FirstName AS 'YardEmployeeFirstName',
           truckType.TruckTypeName AS 'TruckTypeName',
           sch.ScheduleID AS id,
           Cast(customer.CustomerName AS VARCHAR(2000)) + ' - ' + Cast(sch.LotNumber AS VARCHAR(2000)) + ' - ' + Cast(subdivision.SubdivisionName AS VARCHAR(2000)) + ' - ' + Cast(product.ProductName AS VARCHAR(2000)) AS 'title',
           CONVERT(VARCHAR(50), sch.CustomerExpectedDate, 101) + ' ' + CONVERT(VARCHAR, DATEPART(hh, sch.CustomerExpectedDate)) + ':' + RIGHT('0' + CONVERT(VARCHAR, DATEPART(mi, sch.CustomerExpectedDate)), 2) AS 'start',
           CONVERT(VARCHAR(50), DATEADD(hh, 1, sch.CustomerExpectedDate), 101) AS 'end',
           stat.StatusColor AS 'backgroundColor',
           note.NoteText AS 'NoteText'
    FROM s84_Schedule sch
    LEFT OUTER JOIN dbo.s84_ScheduleNotes AS note ON note.ScheduleID = (SELECT MAX(n.ScheduleNoteID) FROM dbo.s84_ScheduleNotes n WHERE n.ScheduleID = sch.ScheduleID)
    JOIN dbo.s84_Installer AS installer ON sch.InstallerID = installer.InstallerID
    JOIN dbo.s84_Customer AS customer on sch.CustomerID = customer.CustomerID
    JOIN dbo.s84_Subdivision AS subdivision ON sch.SubdivisionID = subdivision.SubdivisionID
    JOIN dbo.s84_Product AS product ON sch.ProductID = product.ProductID
    JOIN dbo.s84_FieldRep AS fieldRep ON sch.FieldRepID = fieldRep.FieldRepID
    JOIN dbo.s84_Window AS window ON sch.WindowID = window.WindowID
    JOIN dbo.s84_Store AS store ON sch.StoreID = store.StoreID
    JOIN dbo.s84_Status AS stat ON sch.StatusID = stat.StatusID
    JOIN dbo.s84_TruckType AS truckType ON sch.TruckTypeID = truckType.TruckTypeID
    LEFT OUTER JOIN dbo.s84_Employee AS driver ON ((@DriverVal IS NOT NULL) AND (driver.EmailAddress = @DriverVal))
    LEFT OUTER JOIN dbo.s84_Employee AS yardEmployee ON ((@YardEmployeeVal IS NOT NULL) AND (yardEmployee.EmailAddress = @YardEmployeeVal))
    WHERE
      (@InvoiceNumVal IS NULL OR (sch.InvoiceNumber LIKE '%' + @InvoiceNumVal + '%')) AND
      (@InstallerVal IS NULL OR (installer.InstallerID = @InstallerVal)) AND
      (@CustomerVal IS NULL OR (customer.CustomerName LIKE '%' + @CustomerVal + '%')) AND
      (@SubdivisionVal IS NULL OR (subdivision.SubdivisionName LIKE '%' + @SubdivisionVal + '%')) AND
      (@ProductVal IS NULL OR ( sch.ProductID IN (SELECT * FROM dbo.CSVToTable(@ProductVal)) )) AND
      (@LotNumVal IS NULL OR (sch.LotNumber LIKE '%' + @LotNumVal + '%')) AND
      (@EstimateNumVal IS NULL OR (sch.EstimateNumber LIKE '%' + @EstimateNumVal + '%')) AND
      (@SONumVal IS NULL OR (sch.SONumber LIKE '%' + @SONumVal + '%')) AND
      (@ProdInStoreVal IS NULL OR (sch.ProductInStore = @ProdInStoreVal)) AND
      (@OrderProcessedVal IS NULL OR (sch.OrderProcessed = @OrderProcessedVal)) AND
      (@FieldRepVal IS NULL OR (fieldRep.FieldRepID = @FieldRepVal)) AND
      (@WorkOrderNumVal IS NULL OR (sch.ScheduleID LIKE '%' + @WorkOrderNumVal + '%')) AND
      (@WindowVal IS NULL OR (window.WindowName LIKE '%' + @WindowVal + '%')) AND
      (@StoreVal IS NULL OR (store.StoreName LIKE '%' + @StoreVal + '%')) AND
      (@DriverVal IS NULL OR ((driver.FirstName LIKE '%' + @DriverVal + '%') OR (driver.LastName LIKE '%' + @DriverVal + '%'))) AND
      (@YardEmployeeVal IS NULL OR ((yardEmployee.FirstName LIKE '%' + @YardEmployeeVal + '%') OR (yardEmployee.LastName LIKE '%' + @YardEmployeeVal + '%'))) AND
      (@TruckTypeVal IS NULL OR (truckType.TruckTypeName LIKE '%' + @TruckTypeVal  + '%')) AND
      (@LotNumExact IS NULL OR (sch.LotNumber = @LotNumExact)) AND
      (@StatusIDExact IS NULL OR (sch.StatusID = @StatusIDExact)) AND
      (@CustomerIdRestriction IS NULL OR ( sch.CustomerID IN (SELECT * FROM dbo.CSVToTable(@CustomerIdRestriction)) )) AND

      (@StatusVal IS NULL OR
       ( sch.StatusID IN (SELECT * FROM dbo.CSVToTable(@StatusVal)) OR
         (
           ('9999' IN (SELECT * FROM dbo.CSVToTable(@StatusVal)) ) AND 
           ( sch.StatusID NOT IN (SELECT * FROM (VALUES ('1'), ('2'), ('3'), ('4')) AS X(id)) )
         )
       )
      ) AND

      (((@InstallDateOperator IS NULL) OR (@InstallDateOperator = 99)) OR
        (@InstallDateOperator = 1 AND sch.InstallDate = @InstallDateRange1) OR
        (@InstallDateOperator = 2 AND sch.InstallDate <= @InstallDateRange1) OR
        (@InstallDateOperator = 3 AND sch.InstallDate >= @InstallDateRange1) OR
        (@InstallDateOperator = 4 AND sch.InstallDate >= @InstallDateRange1 AND sch.InstallDate <= @InstallDateRange2) OR
        (@InstallDateOperator = 5 AND sch.InstallDate BETWEEN DATEADD(mm,-@InstallDateDynRange1,GETDATE()) AND DATEADD(mm,@InstallDateDynRange2,GETDATE()))
      ) AND

      (((@CustExpectedOperator IS NULL) OR (@CustExpectedOperator = 99)) OR
        (@CustExpectedOperator = 1 AND sch.CustomerExpectedDate = @CustExpectedRange1) OR
        (@CustExpectedOperator = 2 AND sch.CustomerExpectedDate <= @CustExpectedRange1) OR
        (@CustExpectedOperator = 3 AND sch.CustomerExpectedDate >= @CustExpectedRange1) OR
        (@CustExpectedOperator = 4 AND sch.CustomerExpectedDate >= @CustExpectedRange1 AND sch.CustomerExpectedDate <= @CustExpectedRange2) OR
        (@CustExpectedOperator = 5 AND sch.CustomerExpectedDate BETWEEN DATEADD(mm,-@CustExpectedDynRange1,GETDATE()) AND DATEADD(mm,@CustExpectedDynRange2,GETDATE()))
      ) AND

      (((@CompletedDateOperator IS NULL) OR (@CompletedDateOperator = 99)) OR
        (@CompletedDateOperator = 1 AND sch.CompletedDate = @CompletedDateRange1) OR
        (@CompletedDateOperator = 2 AND sch.CompletedDate <= @CompletedDateRange1) OR
        (@CompletedDateOperator = 3 AND sch.CompletedDate >= @CompletedDateRange1) OR
        (@CompletedDateOperator = 4 AND sch.CompletedDate >= @CompletedDateRange1 AND sch.CompletedDate <= @CompletedDateRange2) OR
        (@CompletedDateOperator = 5 AND sch.CompletedDate BETWEEN DATEADD(mm,-@CompletedDateDynRange1,GETDATE()) AND DATEADD(mm,@CompletedDateDynRange2,GETDATE()))
      ) AND

      (((@ProdInStoreDateOperator IS NULL) OR (@ProdInStoreDateOperator = 99)) OR
        (@ProdInStoreDateOperator = 1 AND sch.ProductInStoreDate = @ProdInStoreDateRange1) OR
        (@ProdInStoreDateOperator = 2 AND sch.ProductInStoreDate <= @ProdInStoreDateRange1) OR
        (@ProdInStoreDateOperator = 3 AND sch.ProductInStoreDate >= @ProdInStoreDateRange1) OR
        (@ProdInStoreDateOperator = 4 AND sch.ProductInStoreDate >= @ProdInStoreDateRange1 AND sch.ProductInStoreDate <= @ProdInStoreDateRange2) OR
        (@ProdInStoreDateOperator = 5 AND sch.ProductInStoreDate BETWEEN DATEADD(mm,-@ProdInStoreDateDynRange1,GETDATE()) AND DATEADD(mm,@ProdInStoreDateDynRange2,GETDATE()))
      ) AND

      ((@SearchText IS NULL) OR
      ( sch.InvoiceNumber LIKE '%' + @SearchText + '%' OR
        installer.InstallerName LIKE '%' + @SearchText + '%' OR
        customer.CustomerName LIKE '%' + @SearchText + '%' OR
        subdivision.SubdivisionName LIKE '%' + @SearchText + '%' OR
        product.ProductName LIKE '%' + @SearchText + '%' OR
        sch.LotNumber LIKE '%' + @SearchText + '%' OR
        sch.EstimateNumber LIKE '%' + @SearchText + '%' OR
        sch.SONumber LIKE '%' + @SearchText + '%' OR
        stat.StatusName LIKE '%' + @SearchText + '%' OR
        fieldRep.FieldRepName LIKE '%' + @SearchText + '%' OR
        sch.ScheduleID LIKE '%' + @SearchText + '%' OR
        window.WindowName LIKE '%' + @SearchText + '%' OR
        store.StoreName LIKE '%' + @SearchText + '%'
      ))
    ORDER BY
      CASE @OrderBy2
      WHEN 1 THEN sch.InstallDate
      WHEN 2 THEN sch.CustomerExpectedDate
      WHEN 3 THEN sch.CustomerExpectedDate
      WHEN 4 THEN sch.CompletedDate
      WHEN 5 THEN sch.InvoiceNumber
      WHEN 6 THEN installer.InstallerName
      WHEN 7 THEN customer.CustomerName
      WHEN 8 THEN subdivision.SubdivisionName
      WHEN 9 THEN product.ProductName
      WHEN 10 THEN sch.LotNumber
      WHEN 11 THEN sch.EstimateNumber
      WHEN 12 THEN sch.SONumber
      WHEN 13 THEN sch.ProductInStore
      WHEN 14 THEN sch.ProductInStoreDate
      WHEN 15 THEN sch.OrderProcessed
      WHEN 16 THEN stat.StatusName
      WHEN 17 THEN fieldRep.FieldRepName
      WHEN 18 THEN window.WindowName
      WHEN 19 THEN store.StoreName
      WHEN 20 THEN driver.LastName
      WHEN 21 THEN yardEmployee.LastName
      ELSE sch.CustomerExpectedDate
      END,
      CASE @OrderBy1
      WHEN 1 THEN sch.InstallDate
      WHEN 2 THEN sch.CustomerExpectedDate
      WHEN 3 THEN sch.CustomerExpectedDate
      WHEN 4 THEN sch.CompletedDate
      WHEN 5 THEN sch.InvoiceNumber
      WHEN 6 THEN installer.InstallerName
      WHEN 7 THEN customer.CustomerName
      WHEN 8 THEN subdivision.SubdivisionName
      WHEN 9 THEN product.ProductName
      WHEN 10 THEN sch.LotNumber
      WHEN 11 THEN sch.EstimateNumber
      WHEN 12 THEN sch.SONumber
      WHEN 13 THEN sch.ProductInStore
      WHEN 14 THEN sch.ProductInStoreDate
      WHEN 15 THEN sch.OrderProcessed
      WHEN 16 THEN stat.StatusName
      WHEN 17 THEN fieldRep.FieldRepName
      WHEN 18 THEN window.WindowName
      WHEN 19 THEN store.StoreName
      WHEN 20 THEN driver.LastName
      WHEN 21 THEN yardEmployee.LastName
      ELSE sch.CustomerExpectedDate
      END;
END;
GO

当我为dbo.GetFilteredSchedule程序提供值时,这些是我设置的变量......

  • 我将ProductVal设置为&#34; 26&#34;
  • 我将StatusVal设置为&#34; 1,3,4,9999&#34;
  • 我将OrderBy1和OrderBy2设置为&#34; 3&#34;
  • 其他一切都是NULL

这是我的桌子看起来像的打印屏幕......

The table

1 个答案:

答案 0 :(得分:1)

这看起来不对:

LEFT OUTER JOIN dbo.s84_ScheduleNotes AS note
    ON note.ScheduleID = (SELECT MAX(n.ScheduleNoteID) FROM dbo.s84_ScheduleNotes n WHERE n.ScheduleID = sch.ScheduleID)

我相信note.ScheduleID应该是note.ScheduleNoteID