PDA

View Full Version : مشکل با SELECT در FETCH



Happy_davood
دوشنبه 16 بهمن 1385, 09:21 صبح
سلام
این عبارات رو در نظر داشته باشید :


DECLARE authors_cursor CURSOR FOR
SELECT au_lname, au_fname FROM authors
WHERE au_lname LIKE "B%"
ORDER BY au_lname, au_fname

OPEN authors_cursor

FETCH NEXT FROM authors_cursor
INTO @au_lname, @au_fname

-- Check @@FETCH_STATUS to see if there are any more rows to fetch.
WHILE @@FETCH_STATUS = 0
BEGIN

-- Concatenate and display the current values in the variables.
PRINT "Author: " + @au_fname + " " + @au_lname

-- This is executed as long as the previous fetch succeeds.
FETCH NEXT FROM authors_cursor
INTO @au_lname, @au_fname
END

حالا فرض کنید این قسمت از Query داخل یک رشته باشه :


SELECT au_lname, au_fname FROM authors
WHERE au_lname LIKE "B%"
ORDER BY au_lname, au_fname

الان چه طوری باید این رشته رو اجرا کنم و بتونم از FETCH هم استفاده کنم .

Kamyar.Kimiyabeigi
دوشنبه 16 بهمن 1385, 10:08 صبح
شما باید کل Script تون را به صورت dynamic بنویسید و در نهایت execute کنید

zerobit-ltd
دوشنبه 16 بهمن 1385, 11:06 صبح
اگر query شما در همین حده، اصلا چرا از cursor استفاده می کنید؟
ولی برای انجام این کار، می تونید نتیجه query که به صورت رشته هستش رو توی یه temp table بریزید و cursor رو از روی اون temp table بسازید.

Happy_davood
دوشنبه 16 بهمن 1385, 20:41 عصر
راه حل جدول Temp به نظرم خوب باشه . آزمایش می کنم . البته اگه بشه Query که بصورت داخل رشته قرار گرفته همونجا اجرا کرد محشر میشه .
البته من می دونم که میشه رشته حاوی Query رو با EXEC اجرا کرد ولی این کار داخل CURSOR نمیشه . شاید هم من بلد نیستم ؟

Kamyar.Kimiyabeigi
سه شنبه 17 بهمن 1385, 07:38 صبح
البته من می دونم که میشه رشته حاوی Query رو با EXEC اجرا کرد ولی این کار داخل CURSOR نمیشه . شاید هم من بلد نیستم ؟
در Script های داینامیک هم میشه از Cursor استفاده کرد :لبخندساده:

Happy_davood
سه شنبه 17 بهمن 1385, 08:53 صبح
نه دیگه اگه قرار باشه Cursor هم بره داخل Script که دیگه همه SP میشه Script.

Kamyar.Kimiyabeigi
سه شنبه 17 بهمن 1385, 09:05 صبح
نه دیگه اگه قرار باشه Cursor هم بره داخل Script که دیگه همه SP میشه Script.

خوب اگر همش داخل Script باشه مشکل کجاست؟

zerobit-ltd
سه شنبه 17 بهمن 1385, 14:31 عصر
از اونجا که رشته ای که توسط exec اجرا می شه، به عنوان یک قطعه کد مجزا اجرا می شه، شما نمی تونید از متغیرها و cursor های داخل اون قطعه کد در بیرون از همون قطعه کد استفاده کنید یا با متغیری رو که خارج از اون رشته تعریف کردید، در داخل رشته مقدار دهی کنید. فکر می کنم تنها راه موجود استفاده از همون temp table باشه.

Kamyar.Kimiyabeigi
سه شنبه 17 بهمن 1385, 15:43 عصر
چرا همه فکر میکنن تنها راه حل Temp Table در صورتی که این چنین نیست. :عصبانی++:
یک نمونه از Execute براتون میزام که در اون از cursor هم استفاده شده


USE Northwind
GO

CREATE PROCEDURE Test @prm VARCHAR(50)
AS
EXECUTE(
'DECLARE @fname VARCHAR(200),
@lname VARCHAR(200)


DECLARE authors_cursor CURSOR FOR
SELECT FirstName, LastName FROM dbo.Employees
WHERE LastName LIKE ' + '''' + '%' + @prm + '%' + '''' +
' ORDER BY LastName, FirstName

OPEN authors_cursor

FETCH NEXT FROM authors_cursor
INTO @fname, @lname

WHILE @@FETCH_STATUS = 0
BEGIN
PRINT (@fname + ' + '''' + ' ' + '''' + ' + @lname)
FETCH NEXT FROM authors_cursor
INTO @fname, @lname
END

CLOSE authors_cursor
DEALLOCATE authors_cursor')
GO

EXECUTE Test 'A'
GO

darvishiali
سه شنبه 17 بهمن 1385, 17:39 عصر
سلام؛

ما باید فقط در موارد خیلی ضروری یه رشته رو با EXECUTE اجرا کنیم. اجرای رشته در SP نه تنها خوب نیست، بلکه ما در واقع از هیچکدام از مزیت های مهم SP استفاده نکردیم!
(از مزیت های مهم SP اینه که Transact-SQL ای که توش نوشته شده، نه از لحاظ Syntax چک میشه و نه از لحاظ وجود Object های استفاده شده داخل اون Transact-SQL)
حالا اگه ما بیایم یه رشته بسازیم و اونو اجرا کنیم، اول باید رشته مون ساخته بشه، بعدش Syntax Checking بشه، بعدش Object هاش چک بشه و ... در ضمن متغیرهای OUTPUT ای که میتونیم توی SP تعریف کنیم هم هست...

zerobit-ltd
سه شنبه 17 بهمن 1385, 19:11 عصر
چرا همه فکر میکنن تنها راه حل Temp Table در صورتی که این چنین نیست. :عصبانی++:
یک نمونه از Execute براتون میزام که در اون از cursor هم استفاده شده


USE Northwind
GO

CREATE PROCEDURE Test @prm VARCHAR(50)
AS
EXECUTE(
'DECLARE @fname VARCHAR(200),
@lname VARCHAR(200)


DECLARE authors_cursor CURSOR FOR
SELECT FirstName, LastName FROM dbo.Employees
WHERE LastName LIKE ' + '''' + '%' + @prm + '%' + '''' +
' ORDER BY LastName, FirstName

OPEN authors_cursor

FETCH NEXT FROM authors_cursor
INTO @fname, @lname

WHILE @@FETCH_STATUS = 0
BEGIN
PRINT (@fname + ' + '''' + ' ' + '''' + ' + @lname)
FETCH NEXT FROM authors_cursor
INTO @fname, @lname
END

CLOSE authors_cursor
DEALLOCATE authors_cursor')
GO

EXECUTE Test 'A'
GO

شما کلاه خودتو قاضی کن. سر و کله زدن با این همه رشته و single quote راحت تره یا استفاده از temp table ؟
من هیچ اصراری ندارم که از temp table استفاده بشه، چون خود microsoft تاکید داره که تا جایی که ممکنه از temp table استفاده نکنیم؛ چون کارایی رو پایین میاره. ولی اینجا از اون جاهایی هستش که مشکلمون با temp table به راحتی حل می شه.
این نکته رو به توضیحات darvishiali اضافه می کنم: رشته هایی که با exec اجرا می شن، نمی تونن cache بشن که این یکی دیگه از دلایلی هستش که نباید زیاد از این دستور استفاده کرد.

Kamyar.Kimiyabeigi
چهارشنبه 18 بهمن 1385, 07:50 صبح
شما کلاه خودتو قاضی کن. سر و کله زدن با این همه رشته و single quote راحت تره یا استفاده از temp table ؟
من هیچ اصراری ندارم که از temp table استفاده بشه، چون خود microsoft تاکید داره که تا جایی که ممکنه از temp table استفاده نکنیم؛ چون کارایی رو پایین میاره. ولی اینجا از اون جاهایی هستش که مشکلمون با temp table به راحتی حل می شه.
این نکته رو به توضیحات darvishiali اضافه می کنم: رشته هایی که با exec اجرا می شن، نمی تونن cache بشن که این یکی دیگه از دلایلی هستش که نباید زیاد از این دستور استفاده کرد.

zerobit-ltd حرف شما کاملاً متین اما اینکه شما صرفاً میگفتین تنها راه حل استفاده از Temp Table هست یک مقدار عجیب بود :متفکر:

zerobit-ltd
چهارشنبه 18 بهمن 1385, 12:53 عصر
من هم اصراری بر به کرسی نشوندن حرفم ندارم. واسه انجام هر کاری کلی راه وجود داره؛ ولی همیشه باید راحت ترین و به صرفه ترین راه رو انتخاب کرد. از اونجایی که برنامه نویسی یه امر کاملا سلیقه ای هستش، انتخاب روش برای انجام هر کاری، مستقیما به شخص برنامه نویس بر می گرده.