T-SQL:如何获取字符串的确切字符长度?

发布于 2024-09-24 07:02:36 字数 569 浏览 7 评论 0原文

我正在为预先没有数据类型信息的表生成 T-SQL SELECT 语句。在这些语句中,我需要执行取决于表列的原始值的长度的字符串操作操作。

一个示例(但不是唯一一个)是在字符串中的特定位置插入一些文本,包括将其插入末尾的选项:(

SELECT 
  CASE WHEN (LEN ([t0].[Product] = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
  END
FROM [OrderItem] [t0]

需要 CASE WHEN + LEN,因为 STUFF 不允许我插入文本位于字符串末尾。)

问题是 LEN 排除了尾随空格,这会破坏计算。 我知道我可以使用 DATALENGTH,它不排除尾随空格,但我无法将 DATALENGTH 返回的字节转换为 STUFF 所需的字符,因为我不知道 Product 列的类型是 varchar 还是 nvarchar。

那么,如何在没有有关所使用的字符串数据类型的预先信息的情况下生成取决于字符串的确切字符长度的 SQL 语句呢?

I'm generating T-SQL SELECT statements for tables for which I have no data type information up-front. In these statements, I need to perform string manipulation operations that depend on the length of the original value of the tables' columns.

One example (but not the only one) is to insert some text at a specific position in a string, including the option to insert it at the end:

SELECT 
  CASE WHEN (LEN ([t0].[Product] = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
  END
FROM [OrderItem] [t0]

(The CASE WHEN + LEN is required because STUFF doesn't allow me to insert text at the end of a string.)

The problem is that LEN excludes trailing blanks, which will ruin the calculation.
I know I can use DATALENGTH, which does not exclude trailing blanks, but I can't convert the bytes returned by DATALENGTH to the characters required by STUFF because I don't know whether the Product column is of type varchar or nvarchar.

So, how can I generate a SQL statement that depends on the exact length of a string in characters without up-front information about the string data type being used?

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

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

发布评论

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

评论(5

浅笑轻吟梦一曲 2024-10-01 07:02:36

以下是我最终使用的结果:

SELECT   
  CASE WHEN ((LEN ([t0].[Product] + '#') - 1) = 8)   
    THEN [t0].[Product] + 'test'   
    ELSE STUFF ([t0].[Product], 8, 0, 'test')   
  END  
FROM [OrderItem] [t0]  

测量表明 LEN (... + '#') - 1 技巧与单独的 LEN (...) 速度大致相同。

感谢所有好的答案!

Here's what I ended up using:

SELECT   
  CASE WHEN ((LEN ([t0].[Product] + '#') - 1) = 8)   
    THEN [t0].[Product] + 'test'   
    ELSE STUFF ([t0].[Product], 8, 0, 'test')   
  END  
FROM [OrderItem] [t0]  

Measurements indicate that the LEN (... + '#') - 1 trick is about the same speed as LEN (...) alone.

Thanks for all the good answers!

溺孤伤于心 2024-10-01 07:02:36

试试这个:

SELECT 
  CASE WHEN (LEN (REPLACE([t0].[Product],' ', '#') = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
  END
FROM [OrderItem] [t0]

try this:

SELECT 
  CASE WHEN (LEN (REPLACE([t0].[Product],' ', '#') = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
  END
FROM [OrderItem] [t0]
变身佩奇 2024-10-01 07:02:36

您不能查找系统表中列的类型信息吗?

如果不是,则确定列是 varchar 还是 nvarchar 就可以了。

create table #test
(
c varchar(50),
n nvarchar(50)
)

insert into #test values ('1,2,3,4    ',N'1,2,3,4,5      ')

SELECT
       CASE
              WHEN datalength(CAST(c AS nvarchar(MAX))) = datalength(c)
              THEN 'c is nvarchar'
              ELSE 'c is char'
       END,
       CASE
              WHEN datalength(CAST(n AS nvarchar(MAX))) = datalength(n)
              THEN 'n is nvarchar'
              ELSE 'n is char'
       END
FROM   #test

Can't you look up the type information for the columns in the system tables?

If not then to determine whether or not a column is varchar or nvarchar this would do it.

create table #test
(
c varchar(50),
n nvarchar(50)
)

insert into #test values ('1,2,3,4    ',N'1,2,3,4,5      ')

SELECT
       CASE
              WHEN datalength(CAST(c AS nvarchar(MAX))) = datalength(c)
              THEN 'c is nvarchar'
              ELSE 'c is char'
       END,
       CASE
              WHEN datalength(CAST(n AS nvarchar(MAX))) = datalength(n)
              THEN 'n is nvarchar'
              ELSE 'n is char'
       END
FROM   #test
櫻之舞 2024-10-01 07:02:36

使用DATALENGTHSQL_VARIANT_PROPERTY

SELECT 
  CASE 
    WHEN 8
      = DATALENGTH([t0].[Product]) 
      / CASE SQL_VARIANT_PROPERTY([t0].[Product],'BaseType') WHEN 'nvarchar' THEN 2 ELSE 1 END
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
  END
FROM [OrderItem] [t0]

Use DATALENGTH and SQL_VARIANT_PROPERTY:

SELECT 
  CASE 
    WHEN 8
      = DATALENGTH([t0].[Product]) 
      / CASE SQL_VARIANT_PROPERTY([t0].[Product],'BaseType') WHEN 'nvarchar' THEN 2 ELSE 1 END
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
  END
FROM [OrderItem] [t0]
逆流 2024-10-01 07:02:36

如果没有前导空格,len(reverse(column_name)) 将为您提供列长度。

If there are no leading blanks, len(reverse(column_name)) will give you the column length.

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