View Full Version : سوال: اجراي پرس و جوي دايناميک بزرگ
m_omrani
سه شنبه 27 مهر 1389, 23:08 عصر
همون طور که مي دونيد با sp_executesql مي شه پرس و جوهاي دايناميک رو اجرا کرد. مشکل من اينه که اندازه پرس و جوي من زياده و با VARCHAR(MAX) نمي تونم تعريفش کنم. از TEXT و NTEXT هم که نمي شه متغير محلي تعريف کرد. چه راهي براي اين کار وجود داره؟
Reza_Yarahmadi
چهارشنبه 28 مهر 1389, 07:54 صبح
يعني كوئري شما از 2,147,483,647 كاراكتر بيشتره؟!!
فكر نميكنم كوئري شما از اين تعداد كاراكتر بتونه بيشتر باشه ، چيزي بيش از ده ميليون خط ميشه باهاش نوشت يعني كوئري شما بيش از اين مقداره؟!! :گیج:
شايد مشكل از جاي ديگه اي باشه ، شايد روش كارتون مشكل داشته باشه ، شايد مشكل به خاطر ورژن sql شما باشه ، شايد .... ولي فكر نميكنم مشكل به خاطر اندازه varchar باشه.
اگر دقيقا بگيد ميخوايد چه كار كنيد ، با چه ورژني كار ميكنيد ، ساختار كلي دستورتون به چه صورته ، ... كلا يه توضيح كاملي بديد راحتتر ميشه كمكتون كرد.
حمیدرضاصادقیان
چهارشنبه 28 مهر 1389, 08:06 صبح
سلام. یعنی حجم کوئری های شما از
max indicates that the maximum storage size is 2^31-1 bytes.
بیشتره!!!!
مگه چه کوئری نوشتید؟؟ فکر میکنم بهتره روشتون رو اصلاح کنید یا کوئری مورد نظر رو به بخش های مختلف مثل Function,View,Sp تبدیل کنید و ازاونها در کوئری اصلیتون استفاده کنید.
در صورت تمایل کوئریتون رو اینجا قرار بدید شاید برای اصلاح اون راههای مناسبتری هم باشه.
موفق باشید
m_omrani
چهارشنبه 28 مهر 1389, 10:05 صبح
دوستان عزيز! اينقدر سريع قضاوت نکنيد. کمي تيزبين باشيد.
ببينيد. شما وقتي مي خواهيد يک پرس و جوي دايناميک درست کنيد و مجبور باشيد متغير تعريف کنيد، نمي تونيد متغير NTEXT يا TEXT تعريف کنيد که. بايد NVARCHAR يا VARCHAR تعريف کنيد. اين دو تا هم فقط مي تونن 4000 بايت باشند نه 2 به توان 31 بايت منهاي يک که شما مي فرماييد!
بنده خودم هم مي دانم که sp_executesql يه NTEXT مي گيره. اما مشکل اينه که پرس و جو رو نمي تونم جدا بسازم تا بهش بدم.
حالا مشکل رو دريافتيد؟
با تشکر
m_omrani
چهارشنبه 28 مهر 1389, 10:23 صبح
مثلاً يک راهش اينه که فردي در اين لينک ارائه داده:
http://sequelserver.blogspot.com/2006/07/spexecutesql-and-long-sql-strings-in.html
DECLARE @sql1 nvarchar(4000),
@sql2 nvarchar(4000),
@state char(2)
SELECT @state = 'CA'
SELECT @sql1 = N'SELECT COUNT(*)'
SELECT @sql2 = N'FROM dbo.authors WHERE state = @state'
EXEC('EXEC sp_executesql N''' + @sql1 + @sql2 + ''',
N''@state char(2)'',
@state = ''' + @state + '''')
اما آيا راه ديگري وجود نداره؟
حمیدرضاصادقیان
چهارشنبه 28 مهر 1389, 10:24 صبح
سلام.
دوستان عزيز! اينقدر سريع قضاوت نکنيد. کمي تيزبين باشيد.
ببخشید کی گفته بیش از 4000 تا نمیتونه باشه؟ اولا که 8000 تا هست.دوما اون عددی هم که براتون نوشتم ازتوی Books online نوشتم که مقدار max متغیر از نوع Varchar هست. اصلا فرض کنیم 4000 بایت.مگه شما دارید چه مقداری پاس میدید یا دارید چه کوئری می سازید که بیش از 4000 بایت نیاز دارید؟
Reza_Yarahmadi
چهارشنبه 28 مهر 1389, 10:40 صبح
توي SQL Server 2000 چيزي كه شما ميگيد درسته يعني براي nvarchar ميشه 4000 كاركتر نوشت و برايvarchar ميشه 8000
ولي از 2005 به بعد و با اضافه شدن (varchar(max اين محدوديت تقريبا از بين رفت.
اگر شما از 2000 استفاده ميكنيد فكر نميكنم راهي داشته باشه.
m_omrani
چهارشنبه 28 مهر 1389, 10:47 صبح
چقدر جالب. دوستان هم آن لاين هستند. :بامزه:
ببينيد. البته به من نخنديد ها. من هم در Books Online خواندم که MAX تا 2 به توان 31 منهاي يک رو در 2005 به بعد مي پذيره. اما نمي دانم چرا نتوانستم ازش استفاده کنم.
ببنيد خيلي ساده. من اين طوري کارم رو انجام دادم.
declare @sql nvarchar(max)
set @sql = N'select ....
...
...
...
'
exec sp_executesql @sql, ...
اما هر کاري کردم ديدم اينه متغير @sql لعنتي بيشتر از 4000 بايت قبول نمي کنه که نمي کنه! حتي با اين که nvarchar(max) هست و از کاراکتر 4001 به بعد را دور مي ريزه.
نمي دانم. شايد هم من هنوز طرز استفاده از nvarchar را بلد نباشم! :لبخندساده:
اگر اشتباهي کرده ام پليز بگيد.
حمیدرضاصادقیان
چهارشنبه 28 مهر 1389, 10:49 صبح
سلام. یک سوال.
این Query که شما دارید می نویسید چقدر طول میکشه تا اجرا بشه؟
بعد چرا می فرمائید نمیتونید کوئری تون رو جداکنید.؟؟؟ مثلا از view یا تابع چرا استفاده نمی کنید؟
نمیتونید کوئری تون و نوع کارتون رو مطرح کنید شاید خیلی راحتتر بتونید به جواب برسید.؟
behrouzlo
چهارشنبه 28 مهر 1389, 10:55 صبح
varchar مقدار max ش 8000 است ولی nvarchar مقدار max ش 4000 است
Reza_Yarahmadi
چهارشنبه 28 مهر 1389, 11:05 صبح
varchar مقدار max ش 8000 است ولی nvarchar مقدار max ش 4000 است نميدونم دوستان اين مطالب رو از كجا پيدا ميكنند!:متفکر:
گفته شده تا 8000 كاراكتر رو بصورت مستقيم ميشه تعريف كرد نه اينكه حداكثر ظرفيت.
كوئري زير رو تست كنيد
Declare @Str varchar(max), @i int
Set @Str = ''
Set @i = 0
While (@i < 10000)
begin
Set @Str = @Str + '0123456789'
Set @i = @i + 1
end
Select Len(@Str)توي كوئري بالا متغير Str دقيقا 100000 كاراكتر گرفته چطور ميگيد نميشه!!!
m_omrani
چهارشنبه 28 مهر 1389, 11:16 صبح
سلام. یک سوال.
این Query که شما دارید می نویسید چقدر طول میکشه تا اجرا بشه؟
بعد چرا می فرمائید نمیتونید کوئری تون رو جداکنید.؟؟؟ مثلا از view یا تابع چرا استفاده نمی کنید؟
نمیتونید کوئری تون و نوع کارتون رو مطرح کنید شاید خیلی راحتتر بتونید به جواب برسید.؟
اي بابا. آقاي صادقيان عزيز. چرا اصرار داريد و فکر مي کنيد کوئري رو اشتباه نوشتم. کوئري به طور جداگانه هيچ ايرادي نداره، درسته، مشکل سرعت هم نداره، مثل برق اجرا مي شه، بعد هم چرا تصور مي کنيد که بايد از view و sp و اين حرفا حتماً استفاده بشه. برخي مواقع هست که شما ترجيح ميديد يا حتي ممکنه ناگزير باشيد که dynamic کار کنيد. مثلاً بنده يکي از دلايلم اينه که مي خوام سر ستون هاي ديتاي برگشتي ام دايناميک باشه. مثلاً چيزي شبيه اين:
declare @lang varchar(3)
declare @col1 nvarchar(30)
declare @col2 nvarchar(30)
if @lang = 'fa'
begin
set @col1 = 'نام'
set @col2 = 'نام خانوادگي'
end
else
begin
set @col1 = 'Firstname'
set @col2 = 'Lastname'
end
declare @sql nvarchar(max)
set @sql = N'
select Firstname as [' + @col1 + '],Lastname as [' + @col2 + '] from person where ...'
exec sp_executesql @sql, ...
حالا متوجه شديد.
با تشکر.
حمیدرضاصادقیان
چهارشنبه 28 مهر 1389, 11:23 صبح
سلام.نه اصراری ندارم که غلط هست.درسته نیاز هست داینامیک اجرا کنید.ولی برای من این جای تعجب داره شما چه نوع کوئری دارید می نویسید که بیش از 4000 کارکتر نیاز دارید.!!!
m_omrani
چهارشنبه 28 مهر 1389, 11:31 صبح
ضمن تشکر از آقاي يار احمدي.
بله. دقيقاً مساله همينه.
موقع تعريف nvarchar(max) و varchar(max) نمي شه بيشتر از 4000 کاراکتر رو يک باره در يک دستور تعريف کرد، اما اگه پرس و جو تون رو به چندين set @sql = @sql + ... بشکنيد، تا همون 2 به توان ... مي شه پرس و جو رو تعريف کرد.
مشکل حل شد. از همه دوستان متشکرم.
ولي اين به لطف SQL Server 2005 به بعد هستش. اگه 2000 باشيد تنها راهتون همونيه که ابتدا لينکش رو دادم.
باز هم ممنون.
Reza_Yarahmadi
چهارشنبه 28 مهر 1389, 11:38 صبح
برای من این جای تعجب داره شما چه نوع کوئری دارید می نویسید که بیش از 4000 کارکتر نیاز دارید.!!!
بعضي مواقع نياز ميشه.
يك نگاه به كوئري ضميمه كنيد.
حمیدرضاصادقیان
چهارشنبه 28 مهر 1389, 11:45 صبح
سلام.البته میشه با مقداری تغییر در ساختار جداول و نوع کوئری خیلی بهینه تر از این کوئری شما کرد.
میشه بعضی از کوئری ها رو به صورت View دراورد یا به صورت Function که یک Table برمیگردونه و اونو با کوئری اصلی join کنید.
که از لحاظ بازدهی نیز بازدهی بیشتری داره.
Reza_Yarahmadi
چهارشنبه 28 مهر 1389, 11:52 صبح
جالبه! شما نگاه نكرده نظر ميديد!!:متفکر:
اگه وقت كرديد و نگاه كرديد ميبينيد كه خيلي از كارها با Function و ... انجام ميشه. چون شرطهاي زيادي بايد بررسي ميشد حجمش زياد شده.
m_omrani
چهارشنبه 28 مهر 1389, 12:15 عصر
من که از خواندن پرس و جوي مزبور (SQLQuery11.sql) ديوانه شدم. اين ديگر چه پرس و جوي دايناميک وحشتناکي است! :لبخندساده:
حمیدرضاصادقیان
چهارشنبه 28 مهر 1389, 12:20 عصر
سلام.
جالبه! شما نگاه نكرده نظر ميديد!!
خیر نگاه کردم نظرمو اعلام کردم.ولی خیلی دقیق بررسیش نکردم.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.