Курсор SQL для проверки количества строк, конкатенации и сохранения во временной таблице - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть одна таблица, содержащая 3 столбца FirstName, LastName, Salary. Итак, мне нужно сделать одну временную переменную таблицу, а затем выполнить операцию над столбцом FirstName, проверяя длину каждого поляЗатем столбец FirstName, если длина меньше или равна 5, тогда он должен вывести name_length, если длина больше 5, тогда он должен вывести имя только в другой временной таблице.Я хочу, чтобы результат был только в одной таблице.

EX: - Rohan, тогда он будет печататься во временной таблице как Rohan_5.если FirstName - прасад, то он выдаст только прасад.

Поэтому, пожалуйста, помогите мне с этим.

DECLARE @fn varchar(50)

DECLARE @ln varchar(50)

DECLARE @sal int

DECLARE zxcv CURSOR FOR

SELECT FirstName, LastName, Salary FROM Persons

OPEN zxcv

FETCH NEXT FROM zxcv
INTO @fn, @ln, @sal

WHILE @@FETCH_STATUS = 0 

BEGIN

 IF LEN(@fn)<=5

 BEGIN

 select concat(FirstName, '_', LEN(FirstName))as FirstName, LastName, Salary from Persons where LEN(FirstName) <= 5 

  END

 ELSE

 BEGIN

 select FirstName, LastName, Salary from Persons where LEN(FirstName) > 5

 END

FETCH NEXT FROM zxcv
    INTO @fn, @ln, @sal

 END

 CLOSE zxcv;

enter image description here DEALLOCATE zxcv;

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Хорошо, мы «будем использовать» курсор, но мы будем пассивно-агрессивными в комментариях для тех, кто сказал вам использовать курсор здесь:

--This whole script should just be the first select used to define the cursor

DECLARE @firstname varchar(50)
DECLARE @lastname varchar(50)
DECLARE @salary int

--But we've been told to use a cursor
CREATE TABLE #Result(FirstName varchar(50), LastName varchar(50), Salary int)
DECLARE zxcv CURSOR FOR
SELECT
    CASE
    WHEN LEN(FirstName) <= 5
        THEN concat(FirstName, '_', LEN(FirstName))
    ELSE
        FirstName END,
    LastName,
    Salary FROM Persons;

OPEN zxcv
FETCH NEXT FROM zxcv
INTO @firstname, @lastname, @salary;

WHILE @@FETCH_STATUS = 0 
BEGIN
    --See how pointless the actions taken in the cursor loop are now?
    INSERT INTO #Result (FirstName,LastName,Salary)
    VALUES (@firstname,@lastname,@salary);

    FETCH NEXT FROM zxcv
    INTO @firstname, @lastname, @salary;
END

CLOSE zxcv;
DEALLOCATE zxcv;

--If for some odd reason, we do need this temp table, it should be a single INSERT ... SELECT
--using the above SELECT
SELECT * FROM #Result;

В отличие от вас, яочевидно, не используя странный SKU, где мы должны платить письмом за присвоение имен нашим переменным, поэтому я дал им более описательные имена (извиняюсь, когда я начинаю писать пассивно-агрессивный, выход из этого режима затруднен: -)

Проблемы в вашем подходе: а) Каждый SELECT, который не назначает переменные, не задает курсор или не следует за INSERT, будет генерировать отдельный набор результатов и б) Вы запрашиваете базуtable (вместо того, чтобы полагаться на другие переменные) внутри цикла курсора, поэтому добавляются другие строки, не связанные с текущей строкой.

Как указано в комментариях, этот должен просто быть:

SELECT
    CASE
    WHEN LEN(FirstName) <= 5
        THEN concat(FirstName, '_', LEN(FirstName))
    ELSE
        FirstName END,
    LastName,
    Salary FROM Persons;

Или, если нам нужна временная таблица:

CREATE TABLE #Result(FirstName varchar(50), LastName varchar(50), Salary int)
INSERT INTO #Result (FirstName,LastName,Salary)
SELECT
    CASE
    WHEN LEN(FirstName) <= 5
        THEN concat(FirstName, '_', LEN(FirstName))
    ELSE
        FirstName END,
    LastName,
    Salary FROM Persons;
0 голосов
/ 28 ноября 2018

Если вы хотите использовать с курсором, чем вы можете использовать, как показано ниже,

DECLARE @fn varchar(50)
DECLARE @ln varchar(50)
DECLARE @sal int

declare @Persons_Temp as table
(
FirstName varchar(20),
LastName varchar(20),
Salary INT
)

DECLARE zxcv CURSOR FOR
SELECT FirstName, LastName, Salary FROM Persons

OPEN zxcv

FETCH NEXT FROM zxcv
INTO @fn, @ln, @sal

WHILE @@FETCH_STATUS = 0 
BEGIN
    IF LEN(@fn)<=5
         BEGIN
            INSERT INTO @Persons_Temp
            SELECT concat(FirstName, '_', LEN(FirstName))as FirstName, LastName, Salary from Persons where LEN(FirstName) <= 5 
         END
    ELSE
        BEGIN
            INSERT INTO @Persons_Temp
            select FirstName, LastName, Salary from Persons where LEN(FirstName) > 5
        END

FETCH NEXT FROM zxcv INTO @fn, @ln, @sal
END
CLOSE zxcv;
deallocate zxcv;

select * from @Persons_Temp;
0 голосов
/ 27 ноября 2018

Вы можете достичь этого без курсора.Пожалуйста, найдите ниже Запрос для того же.

declare @Persons_Temp as table
(
FirstName varchar(20),
LastName varchar(20),
Salary INT
)

INSERT INTO @Persons_Temp
SELECT CASE WHEN LEN(FirstName) <= 5 THEN FirstName + '_' + convert(varchar(20),LEN(FirstName)) 
ELSE FirstName END, LastName, Salary 
FROM Persons


SELECT * FROM @Persons_Temp

Вы также можете использовать временную таблицу вместо таблицы переменных.

...