SQL Server 2008 - 如何将ntext转换为int列表?

时间:2011-12-30 20:44:51

标签: sql sql-server-2008

我有ntext类型的列,我想将其转换为int列表。列名为ValidForCustomers,包含逗号分隔的客户ID。

我知道我可以将其强制转换为nvarchar(max)但是当我这样做时,SQL会抛出错误

  

'附近的语法不正确。'。

查询的一部分

select Items from Split(c.ValidForCustomers, ',')

这是查询

select top 100 
*,c.CouponCode, 
c.Description,
case when c.CouponType = 0 then 'Order - this coupon ONLY applies to the order subtotal'
else 'Product - this coupon ONLY applies to the specified product(s)' end as CouponType,
case when c.DiscountIncludesFreeShipping = 0 then 'No' else 'Yes' end as FreeShiping,
case when c.ExpiresAfterOneUsageByEachCustomer = 0 then 'No' else 'Yes' end as 'ExpiresAfterOneUsageByAnyCustomer',
case when c.ExpiresOnFirstUseByAnyCustomer = 0 then 'No' else 'Yes' end as 'ExpiresOnFirstUseByAnyCustomer',
c.ExpiresAfterNUses,
case when len(CAST(c.ValidForCustomers as nvarchar(max))) = 0 THEN 'No'
    ELSE cstms.CustomerNames END as 'ValidForCustomers',
CASE when LEN(CAST(c.ValidForProducts as nvarchar(max))) = 0 THEN 'No' ELSE 'No' END as 'ValidForProducts',
CASE when LEN(CAST(c.ValidForCategories as nvarchar(max))) = 0 THEN 'No' ELSE 'Yes' END as 'ValidForCategories'
    from Coupon c with(nolock)        
    cross apply ( select CustomerNames = (SELECT SUBSTRING((SELECT ',' + cust.FirstName + ' ' + cust.LastName
                FROM Customer cust
                inner join (select IntegerFromList from dbo.fn_StringListToIntList(CAST(c.ValidFOrCustomers as nvarchar(max)), ',')) sp on (sp.IntegerFromList= cust.CustomerID)                
                ORDER BY cust.FirstName
                FOR XML PATH('')),2,200000))) as cstms

这是转换程序

CREATE FUNCTION [dbo].[fn_StringListToIntList]
(
  @IntegerList  NVARCHAR(MAX),
  @Delimiter    CHAR(1) = '|'
)
RETURNS @IntegersTable TABLE (IntegerFromList  INT)
AS
BEGIN
  IF (@IntegerList IS NULL) OR (LEN(@IntegerList) = 0) OR (@Delimiter IS NULL) RETURN

  DECLARE  @DelimPos INT
  SELECT  @DelimPos = PATINDEX('%' + @Delimiter + '%', @IntegerList)

  WHILE @DelimPos <> 0
  BEGIN
    --If nothing between delims, save as NULL
    IF LEN(SUBSTRING(@IntegerList, 1, @DelimPos - 1)) = 0
      INSERT INTO @IntegersTable(IntegerFromList)  VALUES(NULL)
    ELSE
      INSERT INTO @IntegersTable(IntegerFromList)
      VALUES(CONVERT(INT, SUBSTRING(@IntegerList, 1, @DelimPos - 1)))

    SELECT @IntegerList  = SUBSTRING(@IntegerList, @DelimPos + 1, LEN(@IntegerList))
    SELECT @DelimPos  = PATINDEX('%' + @Delimiter + '%', @IntegerList)
  END --While...

  --If no additional chars after a final delim, treat as an additional NULL
  IF LEN(@IntegerList) = 0
    INSERT INTO @IntegersTable(IntegerFromList)  VALUES(NULL)
  ELSE
    INSERT INTO @IntegersTable(IntegerFromList)  VALUES(CONVERT(INT, @IntegerList))

  RETURN 

END --Function

,错误是

Msg 102, Level 15, State 1, Line 17
Incorrect syntax near '('.

并且语法

一切正常

3 个答案:

答案 0 :(得分:0)

这对于cast来说是一个很好的语法:

select  *
from    dbo.Split(cast(c.ValidForCustomers as nvarchar(max)), ',')

这是否会出错?

当您调用用户定义的函数时,架构dbo不是可选的。

答案 1 :(得分:0)

由于所有数字都是客户的ID,您可以做的是检查每个客户的ID,以检查它是否在列表中。

SELECT Customer.Id
FROM MyTableWithTextField
INNER JOIN Customer
ON MyTableWithTextField.TextField LIKE CAST(Customer.Id AS VARCHAR(10)) + ',%'
OR MyTableWithTextField.TextField LIKE '%,' + CAST(Customer.Id AS VARCHAR(10)) + ',%'
OR MyTableWithTextField.TextField LIKE '%,' + CAST(Customer.Id AS VARCHAR(10))

是的,这很可怕并且可能会表现不佳,但如果您尝试在单个字段中存储可变数量的值,这是不可避免的。更好的想法是创建一个新表。

答案 2 :(得分:0)

我已经创建了返回Customers字符串的自定义函数,

ALTER FUNCTION [dbo].[fn_GetCustomersForCoupon](
    @CouponID int
)
returns nvarchar(MAX)
as
Begin
declare @Str nvarchar(max)
declare @IntTable table ( ID int)
declare @ValidForProducts nvarchar(2000)

select @ValidForProducts = ValidForCustomers from Coupon where CouponID=@CouponID
insert into @IntTable (ID) select * from dbo.fnStringListToIntList(@ValidForProducts, ',')
SELECT @Str = SUBSTRING((select ',' + Replace(p.FirstName + ' ' + p.LastName, '<Name>','') from @IntTable t
inner join Customer p on (p.CustomerID = t.ID)
FOR XML PATH('')),2,200000)

return @Str
end

现在它可以作为一个魅力,但直接来自查询,因为它不起作用的子查询。

相关问题