Sql 传varchar参数(逗号分隔)转成int

本文介绍了一个SQL函数,用于将由逗号等符号分隔的ID字符串拆分成单独的条目,并返回一个表格结果。该函数适用于需要解析ID列表作为输入参数的场景。
 

 

在使用存储过程中,有时需要将一堆的ID合成一个字符串(如:"1,2,3,4...")当作参数传到存储过程中,这时需要将参数中的ID解放出来,函数如下:

 

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[fnSplitStr] (
    @sText      NVARCHAR(Max),
    @sDelim     CHAR(1)
)

RETURNS @retArray TABLE (
    value   VARCHAR(100)
)
AS
BEGIN
	DECLARE 
		@posStart		BIGINT,
		@posNext		BIGINT,
		@valLen			BIGINT,
		@sValue			NVARCHAR(100);

	IF @sDelim IS NULL 
	BEGIN
		IF LEN(@sText)>100 SET @sText = SUBSTRING(@sText, 1, 100)
		
		INSERT @retArray (value)
		VALUES (@sText);
	END
	ELSE
	BEGIN
		SET @posStart = 1;

		WHILE @posStart <= LEN(@sText)
		BEGIN
			SET @posNext = CHARINDEX(@sDelim, @sText, @posStart);

			IF @posNext <= 0 
				SET @valLen = LEN(@sText) - @posStart + 1;
			ELSE
				SET @valLen = @posNext - @posStart;

			SET @sValue = SUBSTRING(@sText, @posStart, @valLen);
			SET @posStart = @posStart + @valLen + 1;

			IF LEN(@sValue) > 0
			BEGIN
				IF LEN(@sValue)>100 SET @sValue = SUBSTRING(@sValue, 1, 100)
				
				INSERT @retArray (value)
				VALUES (@sValue);
			END
		END
	END
	RETURN
END


在需要解析参数的地方调用:--存储过程、函数、sql语句中

inner join dbo.fnSplitStr(@ids,',') id on t.ID = id.Value



@ids即为参数

### 实现方法 为了在 MySQL 中将逗号分隔的字符串换为多列,可以通过创建一个辅助表来帮助解析字符串。该辅助表用于生成一系列连续整数值,以便于通过 `SUBSTRING_INDEX` 函数提取每个子串并将其作为独立的一行或多列展示。 下面是一个具体的例子说明如何实现这一目标: #### 创建测试数据 假设有一个包含逗号分隔值的单个字段的数据集如下所示[^3]: ```sql CREATE TABLE test_table ( id INT AUTO_INCREMENT PRIMARY KEY, str VARCHAR(255) ); INSERT INTO test_table(str) VALUES ('a,b,c,d,e'); ``` #### 构建辅助查询 利用系统自带的帮助主题表 `mysql.help_topic` 或者其他具有递增 ID 的表来进行联合查询,从而达到分割目的。如果无法访问默认的帮助话题表,则可以选择任何合适的替代方案,比如构建自己的数字序列表[^4]。 这里给出基于 `help_topic` 表的方法: ```sql SELECT DISTINCT SUBSTRING_INDEX( SUBSTRING_INDEX(t.str, ',', h.help_topic_id), ',', -1 ) AS value FROM test_table t JOIN mysql.help_topic h ON h.help_topic_id <= LENGTH(t.str) - LENGTH(REPLACE(t.str, ',', '')) + 1; ``` 这段 SQL 查询会返回一个新的结果集,在其中原始字符串被拆解成了多个单独的记录,每一行代表原字符串中的一个元素。 对于希望得到的结果是以列为单位而不是以行为单位的情况,可以考虑调整上述逻辑,使得每次只选取固定数量的部分并将它们分配给不同的新列名下。然而需要注意的是,这种方法通常适用于已知最大可能长度的情况下;否则可能会导致某些情况下缺少必要的输出列或存在多余的空置列[^5]。 例如,如果我们知道输入的最大项数不超过五项,那么可以直接指定五个新的列名称,并相应修改 SELECT 部分的内容: ```sql SELECT MAX(CASE WHEN pos = 1 THEN val END) col1, MAX(CASE WHEN pos = 2 THEN val END) col2, MAX(CASE WHEN pos = 3 THEN val END) col3, MAX(CASE WHEN pos = 4 THEN val END) col4, MAX(CASE WHEN pos = 5 THEN val END) col5 FROM ( SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.str, ',', n.n), ',', -1) as val, n.n as pos FROM test_table t JOIN (SELECT @row := 0) r, (SELECT a.N + b.N * 10 + 1 n FROM (SELECT 0 N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a, (SELECT 0 N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b LIMIT 5 -- Adjust limit according to the maximum expected number of elements. ) n WHERE n.n <= LENGTH(t.str) - LENGTH(REPLACE(t.str, ',', '')) + 1 ) tmp GROUP BY tmp.val IS NOT NULL; ``` 此脚本首先计算出所有潜在的位置编号(pos),接着按照位置对各部分进行分类汇总,最终形成所需的多列结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值