SQL2000切割字符串

本文介绍了一个使用SQL存储过程进行批量数据插入的具体实例。该实例展示了如何通过解析输入的逗号分隔字符串来逐条插入数据,并利用事务确保数据的一致性和完整性。
-- 2
create   proc  mytest1
(
    
@str   varchar ( 50 )
)
as
    
declare   @tmp   varchar ( 50 )

    
while ( charindex ( ' , ' , @str ) > 0 )
    
begin
        
set   @tmp = Substring ( @str , 1 , Charindex ( ' , ' , @str ) - 1 )
        
set   @str = substring ( @str , charindex ( ' , ' , @str ) + 1 , len ( @str ))
        
select   @tmp , @str
    
end     
go
alter   proc  mytest
(
    
@str   varchar ( 50 )
)
as
    
declare   @tmp   varchar ( 50 )

    
while ( len ( @str ) > 0 )
    
begin
        

        
if   charindex ( ' , ' , @str ) <> 0
            
begin  
                
set   @tmp = Substring ( @str , 1 , Charindex ( ' , ' , @str ) - 1 )
                
set   @str = substring ( @str , charindex ( ' , ' , @str ) + 1 , len ( @str ))
            
end
        
else  
            
begin
                
break
            
end

        
select   @tmp , @str
    
end     
go
exec  mytest  ' aaaaa,bbbb,ccc,dd,eeeee,fffff,ggggg '

 

自己试验的一个实例:

 

/* 入库存储过程 */
alter   proc  Store_In
(
        
-- 库单部分
     @CreateDate   datetime ,
    
@UserID   int ,
        
-- 明细部分
     @ProductID   varchar ( 4000 ),     -- 商品ID,主码
     @BatdchCode   varchar ( 4000 ),     -- 次条码
     @IOPrice   varchar ( 4000 ),     -- 价格
     @IOAmount   varchar ( 1000 ),     -- 数量
         -- 库单主键
     @IOId   int  output     -- 订单ID
)
as
begin   tran  store_in_commit
    
-- 插入入库表一条信息
     insert   into  StoreInOut(Flat,CreateDate,UserID)  values ( 1 , @CreateDate , @UserID )
    
select   @IOId = @@identity

    
-- 插入到明细
     declare   @count   int
    
declare   @tmp_ProductID   varchar ( 4000 )     -- 商品ID临时
     declare   @tmp_BatdchCode      varchar ( 4000 )     -- 次条码临时
     declare   @tmp_IOPrice   varchar ( 4000 )     -- 价格临时
     declare   @tmp_IOAmount   varchar ( 1000 )     -- 数量临时

    
declare   @count_BatdchCode   int      -- 商品次码计数
     declare   @count_IOPrice   int          -- 价格计数
     declare   @count_IOAmount   int          -- 数量技术

    
declare   @price   money
    
set   @count = Charindex ( ' , ' , @ProductID )     -- 查找','出现在@str这个字符串第一次的位置
    
    

    
while   @count > 0
    
begin
            
-- 商品ID
         set   @tmp_ProductID = substring ( @ProductID , 1 ,( @count - 1 ))     -- 这个是要插入到表的数据
         set   @ProductID = substring ( @ProductID ,( @count + 1 ),( len ( @ProductID ) - @count ))
        
set   @count = charindex ( ' , ' , @ProductID )
            
-- 次条码        
         set   @count_BatdchCode = Charindex ( ' , ' , @BatdchCode )
        
set   @tmp_BatdchCode = substring ( @BatdchCode , 1 ,( @count_BatdchCode - 1 ))     -- 这个是要插入到表的数据
         set   @BatdchCode = substring ( @BatdchCode ,( @count_BatdchCode + 1 ),( len ( @BatdchCode ) - @count_BatdchCode ))

            
-- 价格
         set   @count_IOPrice = Charindex ( ' , ' , @IOPrice )
        
set   @tmp_IOPrice = substring ( @IOPrice , 1 ,( @count_IOPrice - 1 ))     -- 这个是要插入到表的数据
         set   @IOPrice = substring ( @IOPrice ,( @count_IOPrice + 1 ),( len ( @IOPrice ) - @count_IOPrice ))
        
            
-- 数量
         set   @count_IOAmount = Charindex ( ' , ' , @IOAmount )
        
set   @tmp_IOAmount = substring ( @IOAmount , 1 ,( @count_IOAmount - 1 ))     -- 这个是要插入到表的数据
         set   @IOAmount = substring ( @IOAmount ,( @count_IOAmount + 1 ),( len ( @IOAmount ) - @count_IOAmount ))    

        
set   @price = cast ( @tmp_IOPrice   as   money )
        
insert   into  IOStoreInfo(IOId,
                                ProductID,
                                BatdchCode,
                                IOPrice,
                                IOAmount,
                                Flat)
                    
values ( @IOId ,
                            
@tmp_ProductID ,
                            
@tmp_BatdchCode ,
                            
@price ,
                            
cast ( @tmp_IOAmount   as   int ),
                            
1 )     -- 入库                            
     end
            
-- 插最后一个明细
         set   @price = cast ( @IOPrice   as   money )
        
insert   into  IOStoreInfo(IOId,
                                ProductID,
                                BatdchCode,
                                IOPrice,
                                IOAmount,
                                Flat)
                    
values ( @IOId ,
                            
@ProductID ,
                            
@BatdchCode ,
                            
@price ,
                            
cast ( @IOAmount   as   int ),
                            
1 )     -- 入库        
         -- select @ProductID    --最后一个插入,商品    
commit   tran  store_in_commit
<think>首先,用户的问题是关于在SQL查询中切割字符串的实现方法。我需要根据系统级指令来构建我的回答。 系统级指令: 1. 所有行内数学表达式必须使用$...$格式。 2. 独立公式必须使用$$...$$格式并单独成段。 3. LaTeX语法正确。 4. 使用中文回答。 5. 生成相关问题。 6. 回答中引用的段落末尾自然地添加引用标识。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 参考站内引用: - 引用[1]: SQL按指定字符分割字符串,提到不同数据库系统的方法。 - 引用[2]: SQL Server 的特定函数实现。 - 引用[3]: SQL查询中截取字符串的例子。 - 引用[4]: SQL字符串分割的其他方法。 用户的问题:"我想查找在SQL查询中切割字符串的方法 请问SQL查询中切割字符串的实现方法" 我的回答需要覆盖SQL切割字符串的常见方法,包括不同数据库系统(如MySQL, SQL Server等)的实现。 结构化回答: 1. **介绍**:简要解释SQL切割字符串的必要性和挑战。 2. **方法**:分数据库系统介绍切割字符串的方法。 - 使用引用中的信息,但确保自然融入。 3. **示例**:提供代码示例,如SQL查询。 4. **总结**:给出一般建议。 5. **相关问题**:根据指令生成相关问题。 生成相关问题: - 指令要求生成相关问题,类似于示例中的"快速排序"部分。 使用中文回答。 确保LaTeX语法正确:用户的问题不涉及数学表达式,但如果有,我会用$...$或$$...$$。在这个上下文中,可能不需要数学公式,除非讨论字符串位置索引等。例如,如果提到位置索引,可以用行内格式如$index$。 引用标识:在回答中引用的段落末尾添加引用标识,如[^1]。我需要基于提供的引用。引用[1]到[4]是关于SQL字符串分割的,所以我应该引用它们。 引用内容: - 引用[1]: 提到MySQL和其他数据库的分割方法。 - 引用[2]: SQL Server的具体函数。 - 引用[3]: 截取字符串的例子。 - 引用[4]: 其他分割方法。 在回答中,我需要自然地引用这些内容。 逐步构建回答: 1. **开头**:确认用户需求,解释SQL字符串切割的常见场景。 2. **主体**: - 讨论通用方法。 - 分数据库:MySQL, SQL Server, PostgreSQL等。 - 使用函数如SUBSTRING, CHARINDEX, SPLIT_PART等。 - 提供代码示例。 3. **结尾**:总结建议。 4. **相关问题**:生成3-5个相关问题。 相关问题想法: 1. SQL中如何连接字符串? 2. 不同数据库的字符串函数差异? 3. 如何处理分割字符串的性能问题? 4. 在SQL中提取子字符串的高级技巧? 5. 字符串分割在数据清洗中的应用? 确保回答真实可靠:基于标准SQL和常见数据库实现。 最终回答结构: - 介绍 - 详细方法 - 示例 - 总结 - 相关问题</think>### SQL查询中切割字符串的实现方法 在SQL查询中切割字符串(即根据指定分隔符或位置提取子字符串)是常见的数据处理需求,如解析CSV数据或提取特定字段。由于SQL标准未直接提供内置的字符串分割函数,实现方法因数据库系统而异。下面我将逐步介绍常见数据库的实现方法,包括通用函数和示例代码。回答基于标准SQL语法和常见数据库文档,确保真实可靠[^1][^2][^3][^4]。 --- #### 一、SQL字符串切割的通用概念 字符串切割通常涉及两个场景: 1. **按分隔符分割**:将一个字符串拆分为多个子字符串(如将"a,b,c"分割为"a"、"b"、"c")。 2. **按位置截取**:提取字符串的指定部分(如从第3个字符开始提取5个字符)。 关键函数包括: - `SUBSTRING(str, start, length)`:截取子字符串。 - `CHARINDEX(substr, str)` 或 `POSITION(substr IN str)`:查找子字符串位置。 - `SPLIT_PART()`(部分数据库支持):直接分割字符串。 不同数据库的函数名和语法可能不同,下面分数据库介绍。 #### 二、按数据库系统实现方法 以下是常见数据库的字符串切割方法,参考了标准实现和优化实践[^1][^2][^4]。 1. **SQL Server** - **方法**:使用自定义函数或内置函数组合。SQL Server 没有内置分割函数,但可通过`SUBSTRING`、`CHARINDEX`和循环实现。 - **示例代码**(按分隔符分割): ```sql -- 创建自定义分割函数(参考引用[2]) CREATE FUNCTION dbo.SplitStr (@strInfo NVARCHAR(MAX), @sign NVARCHAR(10)) RETURNS @array TABLE(Item NVARCHAR(MAX)) AS BEGIN DECLARE @index INT, @item NVARCHAR(MAX) SET @index = CHARINDEX(@sign, @strInfo) WHILE @index <> 0 BEGIN SET @item = SUBSTRING(@strInfo, 1, @index-1) INSERT INTO @array(Item) VALUES(@item) SET @strInfo = SUBSTRING(@strInfo, @index+1, LEN(@strInfo)-@index) SET @index = CHARINDEX(@sign, @strInfo) END SET @item = @strInfo IF LEN(@item) > 0 INSERT INTO @array(Item) VALUES(@item) RETURN END GO -- 调用函数:将"a,b,c"按逗号分割 SELECT * FROM dbo.SplitStr('a,b,c', ','); ``` 结果: | Item | |------| | a | | b | | c | - **按位置截取**(使用`SUBSTRING`): ```sql SELECT SUBSTRING('Hello, World!', 8, 5) AS Result; -- 输出"World"[^3] ``` - **优点**:自定义函数可复用;**缺点**:循环处理可能影响性能。 2. **MySQL** - **方法**:MySQL 8.0+ 支持`SUBSTRING_INDEX()`函数,简化分割操作。旧版本需结合`SUBSTRING`和`LOCATE`。 - **示例代码**(按分隔符分割): ```sql -- 使用SUBSTRING_INDEX直接分割(参考引用[1]) SELECT SUBSTRING_INDEX('a,b,c', ',', 1) AS Part1, -- 输出"a" SUBSTRING_INDEX(SUBSTRING_INDEX('a,b,c', ',', 2), ',', -1) AS Part2; -- 输出"b" ``` - 参数说明:`SUBSTRING_INDEX(str, delim, count)`,`count`为正数表示从左开始取,负数表示从右开始。 - **按位置截取**: ```sql SELECT SUBSTRING('Hello, World!', 8, 5) AS Result; -- 输出"World" ``` - **优点**:语法简洁;**缺点**:多次嵌套处理复杂分割时效率低。 3. **PostgreSQL** - **方法**:支持`SPLIT_PART()`函数,是分割字符串的最优方式。 - **示例代码**: ```sql SELECT SPLIT_PART('a,b,c', ',', 1) AS Part1, -- 输出"a" SPLIT_PART('a,b,c', ',', 2) AS Part2; -- 输出"b" ``` - **按位置截取**:使用`SUBSTRING`类似其他数据库。 - **优点**:高效且易读;**缺点**:仅PostgreSQL原生支持。 4. **通用跨数据库方法** - 如果数据库不支持高级函数,可用`SUBSTRING`和位置函数组合: ```sql -- 示例:提取第一个逗号前的子字符串 SELECT SUBSTRING(str, 1, CHARINDEX(',', str) - 1) AS FirstPart FROM (SELECT 'a,b,c' AS str) AS tmp; ``` - **注意**:位置索引从1开始,$index$ 表示查找位置,需处理边界(如分隔符不存在时)。 #### 三、最佳实践与注意事项 - **性能优化**:避免在循环中处理大数据集。对于SQL Server,使用`STRING_SPLIT()`(2016+版本)或优化自定义函数[^2]。 - **常见错误**: - 忽略字符串长度:使用`LEN()`或`LENGTH()`检查长度,避免截取越界。 - 分隔符处理:确保分隔符唯一,或用`TRIM()`去除空格。 - **推荐方法**: - 优先使用数据库内置函数(如PostgreSQL的`SPLIT_PART`)。 - 复杂场景考虑应用层处理(如Python或Java)。 - **引用说明**:以上方法综合了SQL标准实现和引用中的示例,确保可靠[^1][^2][^3][^4]。 --- #### 总结 在SQL切割字符串主要依赖`SUBSTRING`、位置查找函数或数据库特定函数(如`SPLIT_PART`)。选择方法时需考虑数据库类型和性能需求:SQL Server适合自定义函数,MySQL推荐`SUBSTRING_INDEX`,PostgreSQL优先用`SPLIT_PART`。实际查询中,结合`WHERE`子句可进一步过滤结果[^3][^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值