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

发布于 2024-12-23 16:09:06 字数 3033 浏览 0 评论 0原文

我有类型为 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 '('.

,语法一切正常

I have column with the type ntext, and I would like to convert it into list of int. Column is called ValidForCustomers and contains Ids of customers comma separated.

I know I can cast it to nvarchar(max) but when I do it SQL throws error

Incorrect syntax near '.'.

Part of the query

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

This is query

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

This is procedure for converting

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

and the error is

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

and everything is OK with syntax

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

任性一次 2024-12-30 16:09:06

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

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

这会产生错误吗?

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

This would be a good syntax for cast:

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

Does that give an error?

The schema dbo is not optional when you're calling a user-defined function.

疾风者 2024-12-30 16:09:06

由于所有号码都是客户的 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))

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

Since all numbers are ids of customers, what you can instead do is check each customer's id, to check if it's in the list.

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

Yes, this is hideous and will probably perform badly, but that's unavoidable if you try to store a variable number of values in a single field. A much better idea would be to create a new table.

独﹏钓一江月 2024-12-30 16:09:06

我已经创建了用于返回客户字符串的自定义函数,

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

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

I have created custom function for returning string of 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

now it works as a charm, but directly from query, as subquery it doesn't work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文