sql-server - full - w3schools java



একটি কার্সার ব্যবহার না করে টিএসকিউএল একটি টেবিল পরিবর্তনশীল মাধ্যমে লুপ করার একটি উপায় আছে? (14)

@ Pk = @pk + 1 নির্বাচন করুন ভাল হবে: SET @ pk + = @ pk। আপনি যদি টেবিল উল্লেখ না করেন তবে SELECT ব্যবহার করা এড়িয়ে চলুন শুধুমাত্র মান নির্ধারণ করা হয়।

চলুন বলি আমার নিম্নলিখিত টেবিল পরিবর্তনশীল আছে:

declare @databases table
(
    DatabaseID    int,
    Name        varchar(15),   
    Server      varchar(15)
)
-- insert a bunch rows into @databases

যদি আমি সারি দিয়ে পুনরাবৃত্তি করতে চাই তবে একটি কার্সার ঘোষনা এবং ব্যবহার করা আমার একমাত্র বিকল্প? অন্য উপায় আছে?


Answer #1

আপনার স্কিমা পরিবর্তন বা টেম্প টেবিল ব্যবহার ছাড়া অন্য পদ্ধতির:

DECLARE @rowCount int = 0
  ,@currentRow int = 1
  ,@databaseID int
  ,@name varchar(15)
  ,@server varchar(15);

SELECT @rowCount = COUNT(*)
FROM @databases;

WHILE (@currentRow <= @rowCount)
BEGIN
  SELECT TOP 1
     @databaseID = rt.[DatabaseID]
    ,@name = rt.[Name]
    ,@server = rt.[Server]
  FROM (
    SELECT ROW_NUMBER() OVER (
        ORDER BY t.[DatabaseID], t.[Name], t.[Server]
       ) AS [RowNumber]
      ,t.[DatabaseID]
      ,t.[Name]
      ,t.[Server]
    FROM @databases t
  ) rt
  WHERE rt.[RowNumber] = @currentRow;

  EXEC [your_stored_procedure] @databaseID, @name, @server;

  SET @currentRow = @currentRow + 1;
END

Answer #2

আমি সত্যিই বিন্দু দেখতে না কেন আপনি ভয়ঙ্কর cursor ব্যবহার অবলম্বন করতে হবে। কিন্তু আপনি যদি SQL সার্ভার সংস্করণ 2005/2008 ব্যবহার করেন তবে এখানে অন্য একটি বিকল্প রয়েছে
পুনরাবৃত্তি ব্যবহার করুন

declare @databases table
(
    DatabaseID    int,
    Name        varchar(15),   
    Server      varchar(15)
)

--; Insert records into @databases...

--; Recurse through @databases
;with DBs as (
    select * from @databases where DatabaseID = 1
    union all
    select A.* from @databases A 
        inner join DBs B on A.DatabaseID = B.DatabaseID + 1
)
select * from DBs

Answer #3

আমি সেট ভিত্তিক সমাধান প্রদান করতে যাচ্ছি।

insert  @databases (DatabaseID, Name, Server)
select DatabaseID, Name, Server 
From ... (Use whatever query you would have used in the loop or cursor)

এটি কোনও লুপিং প্রযুক্তি থেকে অনেক দ্রুত এবং লেখার এবং বজায় রাখা সহজ।


Answer #4

এই কোড আমি 2008 R2 ব্যবহার করছি। আমি যে কোডটি ব্যবহার করছি তা হল কী ক্ষেত্রগুলিতে সূচী তৈরি করা (SSNO এবং EMPR_NO) n সব গল্প

if object_ID('tempdb..#a')is not NULL drop table #a

select 'IF EXISTS (SELECT name FROM sysindexes WHERE name ='+CHAR(39)+''+'IDX_'+COLUMN_NAME+'_'+SUBSTRING(table_name,5,len(table_name)-3)+char(39)+')' 
+' begin DROP INDEX [IDX_'+COLUMN_NAME+'_'+SUBSTRING(table_name,5,len(table_name)-3)+'] ON '+table_schema+'.'+table_name+' END Create index IDX_'+COLUMN_NAME+'_'+SUBSTRING(table_name,5,len(table_name)-3)+ ' on '+ table_schema+'.'+table_name+' ('+COLUMN_NAME+') '   'Field'
,ROW_NUMBER() over (order by table_NAMe) as  'ROWNMBR'
into #a
from INFORMATION_SCHEMA.COLUMNS
where (COLUMN_NAME like '%_SSNO_%' or COLUMN_NAME like'%_EMPR_NO_')
    and TABLE_SCHEMA='dbo'

declare @loopcntr int
declare @ROW int
declare @String nvarchar(1000)
set @loopcntr=(select count(*)  from #a)
set @ROW=1  

while (@ROW <= @loopcntr)
    begin
        select top 1 @String=a.Field 
        from #A a
        where a.ROWNMBR = @ROW
        execute sp_executesql @String
        set @ROW = @ROW + 1
    end 

Answer #5

এই পদ্ধতির শুধুমাত্র একটি পরিবর্তনশীল প্রয়োজন এবং @ ডাটাবেস থেকে কোন সারি মুছে না। আমি জানি এখানে অনেকগুলি উত্তর আছে, তবে আমি এমন একটি দেখি না যা আপনার পরবর্তী আইডি পেতে MIN ব্যবহার করে।

DECLARE @databases TABLE
(
    DatabaseID    int,
    Name        varchar(15),   
    Server      varchar(15)
)

-- insert a bunch rows into @databases

DECLARE @CurrID INT

SELECT @CurrID = MIN(DatabaseID)
FROM @databases

WHILE @CurrID IS NOT NULL
BEGIN

    -- Do stuff for @CurrID

    SELECT @CurrID = MIN(DatabaseID)
    FROM @databases
    WHERE DatabaseID > @CurrID

END

Answer #6

এইভাবে আমি এটা করি:

declare @RowNum int, @CustId nchar(5), @Name1 nchar(25)

select @CustId=MAX(USERID) FROM UserIDs     --start with the highest ID
Select @RowNum = Count(*) From UserIDs      --get total number of records
WHILE @RowNum > 0                          --loop until no more records
BEGIN   
    select @Name1 = username1 from UserIDs where USERID= @CustID    --get other info from that row
    print cast(@RowNum as char(12)) + ' ' + @CustId + ' ' + @Name1  --do whatever

    select top 1 @CustId=USERID from UserIDs where USERID < @CustID order by USERID desc--get the next one
    set @RowNum = @RowNum - 1                               --decrease count
END

কোন কার্সার, কোন অস্থায়ী টেবিল, কোন অতিরিক্ত কলাম। USERID কলামটি একটি অনন্য পূর্ণসংখ্যা হওয়া উচিত, কারণ বেশিরভাগ প্রাথমিক কীগুলি হয়।


Answer #7

এখানে আমার সমাধান, যা একটি অসীম লুপ, BREAK বিবৃতি এবং @@ROWCOUNT ফাংশন ব্যবহার করে। কোন কার্সার বা অস্থায়ী টেবিল প্রয়োজন নেই, এবং আমি শুধুমাত্র @databases টেবিলে পরবর্তী সারি পেতে একটি প্রশ্ন লিখতে হবে:

declare @databases table
(
    DatabaseID    int,
    [Name]        varchar(15),   
    [Server]      varchar(15)
);


-- Populate the [@databases] table with test data.
insert into @databases (DatabaseID, [Name], [Server])
select X.DatabaseID, X.[Name], X.[Server]
from (values 
    (1, 'Roger', 'ServerA'),
    (5, 'Suzy', 'ServerB'),
    (8675309, 'Jenny', 'TommyTutone')
) X (DatabaseID, [Name], [Server])


-- Create an infinite loop & ensure that a break condition is reached in the loop code.
declare @databaseId int;

while (1=1)
begin
    -- Get the next database ID.
    select top(1) @databaseId = DatabaseId 
    from @databases 
    where DatabaseId > isnull(@databaseId, 0);

    -- If no rows were found by the preceding SQL query, you're done; exit the WHILE loop.
    if (@@ROWCOUNT = 0) break;

    -- Otherwise, do whatever you need to do with the current [@databases] table row here.
    print 'Processing @databaseId #' + cast(@databaseId as varchar(50));
end

Answer #8

এটি করার জন্য একটি কার্সার ব্যবহার করা সম্ভব:

ফাংশন তৈরি করুন [dbo] .f_teste_loop @tabela টেবিলটি ফেরত দেয় (কোড int, nome varchar (10)) শুরুতে

insert into @tabela values (1, 'verde');
insert into @tabela values (2, 'amarelo');
insert into @tabela values (3, 'azul');
insert into @tabela values (4, 'branco');

return;

শেষ

প্রক্রিয়া তৈরি [dbo]। [sp_teste_loop] শুরু হিসাবে

DECLARE @cod int, @nome varchar(10);

DECLARE curLoop CURSOR STATIC LOCAL 
FOR
SELECT  
    cod
   ,nome
FROM 
    dbo.f_teste_loop();

OPEN curLoop;

FETCH NEXT FROM curLoop
           INTO @cod, @nome;

WHILE (@@FETCH_STATUS = 0)
BEGIN
    PRINT @nome;

    FETCH NEXT FROM curLoop
           INTO @cod, @nome;
END

CLOSE curLoop;
DEALLOCATE curLoop;

শেষ


Answer #9

ধাপ 1: নির্বাচিত বিবৃতি নীচে প্রতিটি রেকর্ডের জন্য অনন্য সারি নম্বর সহ একটি টেম্প টেবিল তৈরি করে।

select eno,ename,eaddress,mobno int,row_number() over(order by eno desc) as rno into #tmp_sri from emp 

পদক্ষেপ 2: প্রয়োজনীয় ভেরিয়েবল ঘোষণা

DECLARE @ROWNUMBER INT
DECLARE @ename varchar(100)

পদক্ষেপ 3: মোট সারি টেম্প টেবিল থেকে গণনা নিন

SELECT @ROWNUMBER = COUNT(*) FROM #tmp_sri
declare @rno int

ধাপ 4: অনন্য সারি নম্বর উপর ভিত্তি করে লুপ টেম্প টেবিল temp তৈরি

while @rownumber>0
begin
  set @rno[email protected]rownumber
  select @ename=ename from #tmp_sri where rno[email protected]rno  **// You can take columns data from here as many as you want**
  set @rownumber[email protected]rownumber-1
  print @ename **// instead of printing, you can write insert, update, delete statements**
end

Answer #10

প্রথমত আপনাকে অবশ্যই নিশ্চিত হওয়া উচিত যে আপনাকে প্রতিটি সারির মাধ্যমে পুনরাবৃত্তি করতে হবে - সেট ভিত্তিক ক্রিয়াকলাপগুলি আমি মনে করতে পারি এমন প্রতিটি ক্ষেত্রে দ্রুত সঞ্চালন করবে এবং সাধারণত সহজ কোড ব্যবহার করবে।

আপনার ডাটার উপর নির্ভর করে নীচের দেখানো নির্বাচন বিবৃতি ব্যবহার করে লুপ করা সম্ভব হতে পারে:

Declare @Id int

While (Select Count(*) From ATable Where Processed = 0) > 0
Begin
    Select Top 1 @Id = Id From ATable Where Processed = 0

    --Do some processing here

    Update ATable Set Processed = 1 Where Id = @Id 

End

আরেকটি বিকল্প একটি অস্থায়ী টেবিল ব্যবহার করা হয়:

Select *
Into   #Temp
From   ATable

Declare @Id int

While (Select Count(*) From #Temp) > 0
Begin

    Select Top 1 @Id = Id From #Temp

    --Do some processing here

    Delete #Temp Where Id = @Id

End

আপনি নির্বাচন করুন অপশন সত্যিই আপনার তথ্য গঠন এবং ভলিউম উপর নির্ভর করে।

দ্রষ্টব্য: আপনি যদি SQL সার্ভার ব্যবহার করেন তবে আপনি আরও ভালভাবে ব্যবহার করা হবে:

WHILE EXISTS(SELECT * FROM #Temp)

COUNT ব্যবহার করে টেবিলে প্রতি একক সারি স্পর্শ করতে হবে, EXISTS শুধুমাত্র প্রথমটি স্পর্শ করতে হবে (নীচে জোসেফের উত্তর দেখুন)।


Answer #11

যদি আপনার একটি অনন্য আইডি থাকে তবে আপনি অফসেট আনফিট ব্যবহার করে পছন্দ করেন:

DECLARE @TableVariable (ID int, Name varchar(50));
DECLARE @RecordCount int;
SELECT @RecordCount = COUNT(*) FROM @TableVariable;

WHILE @RecordCount > 0
BEGIN
SELECT ID, Name FROM @TableVariable ORDER BY ID OFFSET @RecordCount - 1 FETCH NEXT 1 ROW;
SET @RecordCount = @RecordCount - 1;
END

এইভাবে আমি টেবিলে ক্ষেত্র যুক্ত করতে বা উইন্ডো ফাংশন ব্যবহার করার প্রয়োজন নেই।


Answer #12

যদি আপনি টেবিলে একটি পূর্ণসংখ্যা ID থাকে, অতিরিক্ত টেবিল তৈরি না করে লাইটওয়েট

Declare @id int = 0, @anything nvarchar(max)
WHILE(1=1) BEGIN
  Select Top 1 @anything=[Anything],@id[email protected]id+1 FROM Table WHERE ID>@id
  if(@@ROWCOUNT=0) break;

  --Process @anything

END

Answer #13

শুধু একটি দ্রুত নোট, যদি আপনি SQL সার্ভার (2008 এবং তারপরে) ব্যবহার করছেন, উদাহরণ আছে:

While (Select Count(*) From #Temp) > 0

ভাল সঙ্গে পরিবেশিত হবে

While EXISTS(SELECT * From #Temp)

গণনা টেবিলে প্রতি একক সারি স্পর্শ করতে হবে, EXISTS শুধুমাত্র প্রথম এক স্পর্শ করতে হবে।





loops