SQL Server中的游标

时间:2016-02-24 17:06:44

标签: sql sql-server cursors charindex

我尝试了很多代码,但它没用。

所以,我需要的是为只有一个完整名称的表设置一个游标:

create database DB01

use DB01

create table Clients
(
     complete_name varchar(50)
)

insert into Clients 
values ('Ralph Van Beethoven')

没问题。

现在,我有另一个数据库,我必须将我的名字分为姓名,姓氏和姓氏,所以它必须是这样的:

  • 姓名:拉尔夫
  • 姓氏:Van
  • 第二姓:贝多芬

代码:

create database DB02

use DB02

create table Clients_Details
(
     Name varchar(50),
     First_Last_Name varchar(50),
     Second_Last_Name varchar(50)
)

这是真实的事情。我需要一个游标来分离DB01中的完整名称并将其插入到DB02中,我有这个代码:

Declare @name as varchar(50)
Declare cClients cursor for Select complete_name from Clients

Declare @temporal table 
(
    tName varchar(50),
    tFLName varchar(50),
    tSLName varchar(50)
)

Open cClients

Fetch cClients into @name

While (@@fetch_status = 0 )
Begin
    Insert into @temporal
        Select 
            case charindex(' ', @name) 
               when 0 then @name 
               else left(@nname, charindex(' ', @name) - 1) 
            end as tFLName,   
            case charindex(' ', @name) 
               when 0 then null 
               else right(@nname, len(@name) - charindex(' ', @nombre)) 
            end as tSLName
        from 
            Clients

        Insert into BD02.dbo.Clients_Details 
            select tName, tFLName, tSLName 
            from @temporal

    Fetch cClientes into @namecursor
End

Close cClients
Deallocate cClients

它会抛出错误

  

列的名称或指定的列与定义

不匹配

所以我猜测我的错误在charindex,因为它只保存了姓氏和姓氏,但我不太清楚现在要做什么。

有人可以帮助我吗?

2 个答案:

答案 0 :(得分:4)

首先,您不需要游标来执行此操作

Insert into BD02.dbo.Clients_Details(tName,tFLName,tSLName)
SELECT NAME= Reverse(Parsename(Replace(Reverse(complete_name), ' ', '.'), 1)),
       First_Last_Name= Reverse(Parsename(Replace(Reverse(complete_name), ' ', '.'), 2)),
       Second_Last_Name= Reverse(Parsename(Replace(Reverse(complete_name), ' ', '.'), 3))
FROM   Clients 

结果

╔═══════╦═════════════════╦══════════════════╗
║ NAME  ║ First_Last_Name ║ Second_Last_Name ║
╠═══════╬═════════════════╬══════════════════╣
║ Ralph ║ Van             ║ Beethoven        ║
╚═══════╩═════════════════╩══════════════════╝

为您的教授(不推荐

DECLARE @name AS VARCHAR(50)
DECLARE cClients CURSOR FOR
  SELECT complete_name
  FROM   Clients

OPEN cClients
FETCH cClients INTO @name

WHILE ( @@FETCH_STATUS = 0 )
  BEGIN
      INSERT INTO Clients_Details
      SELECT NAME= Reverse(Parsename(Replace(Reverse(@name), ' ', '.'), 1)),
             First_Last_Name= Reverse(Parsename(Replace(Reverse(@name), ' ', '.'), 2)),
             Second_Last_Name= Reverse(Parsename(Replace(Reverse(@name), ' ', '.'), 3))

      FETCH cClients INTO @name
  END

CLOSE cClients

DEALLOCATE cClients 

答案 1 :(得分:1)

我有一个分割功能,可以一直回到我的SQL Server 2000天......

CREATE FUNCTION [dbo].[ufn_Split] 
    (
        @str_in VARCHAR(8000),
        @separator VARCHAR(4)
    )
RETURNS @strtable TABLE (pos int PRIMARY KEY NOT NULL, value varchar(8000))
AS
BEGIN
    DECLARE
    @Occurrences INT,
    @Counter INT,
    @tmpStr VARCHAR(8000)

    SET @Counter = 0
    IF SUBSTRING(@str_in,LEN(@str_in),1) <> @separator 
    SET @str_in = @str_in + @separator
    SET @Occurrences = (DATALENGTH(REPLACE(@str_in,@separator,@separator+'#')) - DATALENGTH(@str_in))/ DATALENGTH(@separator)
    SET @tmpStr = @str_in
    WHILE @Counter <= @Occurrences 
    BEGIN
        SET @Counter = @Counter + 1
        INSERT INTO @strtable
        VALUES  (@Counter, SUBSTRING(@tmpStr, 1, CHARINDEX(@separator,@tmpStr) - 1))
        SET @tmpStr = SUBSTRING(@tmpStr,CHARINDEX(@separator,@tmpStr)+1,8000)
        IF DATALENGTH(@tmpStr) = 0
        BREAK
    END
    RETURN 
END