سؤال

والمشكلة الرئيسية هي حول تغيير مؤشر الصفوف 1،2،3 .. حيث الاتصال والهوية ونوع هو نفسه. ولكن كل الأعمدة يمكن أن تحتوي بالضبط نفس البيانات بسبب بعض السابقين موظف عابث وتحديث كافة الصفوف عن طريق الاتصال معرف والنوع. بطريقة أو بأخرى هناك الصفوف التي لم يتم عابث ولكن الصفوف المؤشر هي نفسها. انها فوضى تامة.

ولقد حاولت استخدام مؤشر الداخلي مع المتغيرات القادمة من المؤشر الخارجي. ولكن يبدو أن لها عالقة في المؤشر الداخلي.

وهناك جزء من الاستعلام يبدو مثل هذا:

Fetch NEXT FROM OUTER_CURSOR INTO @CONTACT_ID,  @TYPE
While (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)

    DECLARE INNER_CURSOR Cursor 
    FOR 
    SELECT * FROM CONTACTS
    where CONTACT_ID = @CONTACT_ID
    and TYPE = @TYPE 

    Open INNER_CURSOR 

    Fetch NEXT FROM INNER_CURSOR 
    While (@@FETCH_STATUS <> -1)
    BEGIN
    IF (@@FETCH_STATUS <> -2)

وماذا يمكن أن تكون المشكلة؟ هلFETCH_STATUS غامضة أو شيء من هذا؟

وتحرير: كل شيء تبدو على ما يرام إذا كنت لا تستخدم هذا الرمز داخل المؤشر الداخلي:

UPDATE CONTACTS
SET INDEX_NO = @COUNTER
where current of INNER_CURSOR

وتحرير: هنا هو صورة كبيرة:

BEGIN TRAN

DECLARE @CONTACT_ID VARCHAR(15)
DECLARE @TYPE VARCHAR(15)
DECLARE @INDEX_NO  SMALLINT
DECLARE @COUNTER SMALLINT
DECLARE @FETCH_STATUS INT 

DECLARE OUTER_CURSOR CURSOR 

FOR 

SELECT CONTACT_ID, TYPE, INDEX_NO FROM CONTACTS
WHERE  
CONTACT_ID IN (SELECT CONTACT_ID FROM dbo.CONTACTS
WHERE CONTACT_ID IN(...)
GROUP BY CONTACT_ID, TYPE, INDEX_NO
HAVING COUNT(*) > 1

OPEN OUTER_CURSOR 

FETCH NEXT FROM OUTER_CURSOR INTO @CONTACT_ID,  @TYPE, @INDEX_NO
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)

SET @COUNTER = 1

        DECLARE INNER_CURSOR CURSOR 
        FOR 
        SELECT * FROM CONTACTS
        WHERE CONTACT_ID = @CONTACT_ID
        AND TYPE = @TYPE 
        FOR UPDATE 

        OPEN INNER_CURSOR 

        FETCH NEXT FROM INNER_CURSOR 

        WHILE (@@FETCH_STATUS <> -1)
        BEGIN
        IF (@@FETCH_STATUS <> -2)

        UPDATE CONTACTS
        SET INDEX_NO = @COUNTER
        WHERE CURRENT OF INNER_CURSOR

        SET @COUNTER = @COUNTER + 1

        FETCH NEXT FROM INNER_CURSOR 
        END
        CLOSE INNER_CURSOR
        DEALLOCATE INNER_CURSOR

FETCH NEXT FROM OUTER_CURSOR INTO @CONTACT_ID,  @TYPE, @INDEX_NO
END
CLOSE OUTER_CURSOR
DEALLOCATE OUTER_CURSOR

COMMIT TRAN
هل كانت مفيدة؟

المحلول 6

وأنا لا أفهم تماما ما كانت المشكلة مع "تحديث تيار المؤشر" ولكن يتم حلها باستخدام عبارة إحضار مرتين لالمؤشر الداخلي:

FETCH NEXT FROM INNER_CURSOR

WHILE (@@FETCH_STATUS <> -1)
BEGIN

UPDATE CONTACTS
SET INDEX_NO = @COUNTER
WHERE CURRENT OF INNER_CURSOR

SET @COUNTER = @COUNTER + 1

FETCH NEXT FROM INNER_CURSOR
FETCH NEXT FROM INNER_CURSOR
END

نصائح أخرى

لديك مجموعة متنوعة من المشاكل. أولا، لماذا أنت باستخدامالقيم FETCH_STATUS المحددة الخاصة بك؟ وينبغي أن يكون مجردFETCH_STATUS = 0.

وثانيا، كنت لا اختيار المؤشر الداخلية الخاصة بك في أي شيء. وأنا لا أستطيع التفكير في أي ظرف من الظروف حيث كنت تحديد كافة الحقول في هذه الطريقة - توضيح بها

وفيما يلي عينة ليذهب بها. مجلد يحتوي على المفتاح الأساسي "ClientID" الذي هو أيضا مفتاح خارجي للحضور. أنا فقط طباعة جميع من UIDs حضور، موزعة حسب ClientID المجلد:

Declare @ClientID int;
Declare @UID int;

DECLARE Cur1 CURSOR FOR
    SELECT ClientID From Folder;

OPEN Cur1
FETCH NEXT FROM Cur1 INTO @ClientID;
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT 'Processing ClientID: ' + Cast(@ClientID as Varchar);
    DECLARE Cur2 CURSOR FOR
        SELECT UID FROM Attend Where ClientID=@ClientID;
    OPEN Cur2;
    FETCH NEXT FROM Cur2 INTO @UID;
    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT 'Found UID: ' + Cast(@UID as Varchar);
        FETCH NEXT FROM Cur2 INTO @UID;
    END;
    CLOSE Cur2;
    DEALLOCATE Cur2;
    FETCH NEXT FROM Cur1 INTO @ClientID;
END;
PRINT 'DONE';
CLOSE Cur1;
DEALLOCATE Cur1;

وأخيرا، هل أنت <م> SURE تريد أن تفعل شيئا من هذا القبيل في إجراء مخزن؟ فمن السهل جدا للإساءة الإجراءات المخزنة، وغالبا ما يعكس مشاكل في تشخيص مشكلتك. العينة أعطى، على سبيل المثال، يمكن أن يكون بعيدا بسهولة أكثر إنجازه باستخدام مكالمات مختارة القياسية.

ويمكن أيضا تجنب القضايا المتداخلة المؤشر، وقضايا المؤشر العام، والقضايا المتغيرة العالمية عن طريق تجنب المؤشرات تماما.

declare @rowid int
declare @rowid2 int
declare @id int
declare @type varchar(10)
declare @rows int
declare @rows2 int
declare @outer table (rowid int identity(1,1), id int, type varchar(100))
declare @inner table (rowid int  identity(1,1), clientid int, whatever int)

insert into @outer (id, type) 
Select id, type from sometable

select @rows = count(1) from @outer
while (@rows > 0)
Begin
    select top 1 @rowid = rowid, @id  = id, @type = type
    from @outer
    insert into @innner (clientid, whatever ) 
    select clientid whatever from contacts where contactid = @id
    select @rows2 = count(1) from @inner
    while (@rows2 > 0)
    Begin
        select top 1 /* stuff you want into some variables */
        /* Other statements you want to execute */
        delete from @inner where rowid = @rowid2
        select @rows2 = count(1) from @inner
    End  
    delete from @outer where rowid = @rowid
    select @rows = count(1) from @outer
End

هل لديك أي مزيد من عمليات الجلب؟ يجب أن تظهر تلك أيضا. كنت تظهر لنا فقط نصف التعليمات البرمجية.

وينبغي أن تبدو مثل:

FETCH NEXT FROM @Outer INTO ...
WHILE @@FETCH_STATUS = 0
BEGIN
  DECLARE @Inner...
  OPEN @Inner
  FETCH NEXT FROM @Inner INTO ...
  WHILE @@FETCH_STATUS = 0
  BEGIN
  ...
    FETCH NEXT FROM @Inner INTO ...
  END
  CLOSE @Inner
  DEALLOCATE @Inner
  FETCH NEXT FROM @Outer INTO ...
END
CLOSE @Outer
DEALLOCATE @Outer

وأيضا، تأكد من أنك لا اسم المؤشرات نفسها ... وأي رمز (راجع مشغلات الخاص) أن يحصل على استدعاء لا يستخدم المؤشر الذي يسمى نفسه. رأيت السلوك الغريب من الأشخاص الذين يستخدمون "theCursor 'في طبقات متعددة من المكدس.

وهذا تفوح منها رائحة شيء ينبغي القيام به مع التسجيل بدلا من ذلك. يمكنك مشاركة مشكلة أكبر معنا؟


ومهلا، أنا يجب أن تكون قادرة على الحصول على هذا إلى بيان واحد، ولكن لم تتح لي الوقت للعب مع أكثر من ذلك بعد اليوم وقد لا تحصل على. في الوقت المتوسط، ونعرف أن يجب أن تكون قادرا على تحرير الاستعلام عن المؤشر الداخلية الخاصة بك لإنشاء أرقام الصفوف كجزء من الاستعلام باستخدام في ROW_NUMBER () وظيفة. من هناك، يمكنك أضعاف المؤشر الداخلي إلى الخارجي عن طريق القيام على INNER JOIN على ذلك (يمكنك الانضمام إلى استعلام فرعي). وأخيرا، يمكن تحويل أي عبارة SELECT إلى UPDATE باستخدام هذا الأسلوب:

UPDATE [YourTable/Alias]
   SET [Column] = q.Value
FROM
(
   ... complicate select query here ...
) q

وأين [YourTable/Alias] هو جدول أو الاسم المستعار المستخدمة في استعلام تحديد.

وكان لي نفس المشكلة،

ما عليك فعله هو أن يعلن المؤشر الثاني على النحو التالي: نعلن [second_cursor] المؤشر المحلي ل

وترى "المؤشر المحلي FOR" بدلا من "CURSOR FOR"

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top