PDA

View Full Version : سوال: بدست آوردن متن sql و پارامترها بصورت string



AmirSky
چهارشنبه 10 خرداد 1391, 14:07 عصر
باسلام
فکر کنم با مثال سوالم رو بپرسم بهتر باشه

qry1.SQL.Clear;
qry1.SQL.Add(' SELECT * FROM tbl_animals WHERE Title=:Title ' );
qry1.Parameters.ParamByName('Title').value := 1000;
ShowMessage(qry1.SQL.Text);

که میخوام مقدار :
SELECT * FROM tbl_animals WHERE Title= 1000
رو بدست بیارم

esteghamat
چهارشنبه 10 خرداد 1391, 16:42 عصر
خوب حالا سوالت چيه ؟
همه چيزو كه گفتي .

AmirSky
چهارشنبه 10 خرداد 1391, 19:20 عصر
خروجی کد های بالا به این صورته:
SELECT * FROM tbl_animals WHERE Title=:Title
که من این رو میخوام:
SELECT * FROM tbl_animals WHERE Title= 1000

tiphooo
چهارشنبه 10 خرداد 1391, 20:21 عصر
شما به صورت زیر کد را بنویسی بهتر است و نیازی به تعریف پارامتر نیست
اگر فرض کنیم مقدار 1000 شما در یک متغیر به نام X قرار دارد به صورت زیر عمل کنید
qry1.SQL.Clear;
qry1.Sql.Text:='SELECT * FROM tbl_animals WHERE Title='+ IntToStr(X);
یا
qry1.SQL.add('SELECT * FROM tbl_animals WHERE Title='+IntToStr(X));

AmirSky
چهارشنبه 10 خرداد 1391, 21:02 عصر
1 - یه نرم افزار با نزدیک به صد هزار خط رو نمیتونم تغییر بدم و باید به همین روش باشه
2 - این یه مثال ساده بود . توی کوئری های برزگتر ، مخصوصا UPDATE و INSERT با این روش کار خیلی سخت میشه پس بهتره با پارامتر متغیر داده بشه

tiphooo
پنج شنبه 11 خرداد 1391, 03:40 صبح
اگر فقط برای تسط مقدار دهی به پارامترها می خواهی که راههای گرفتن مقدار پارامترها زیاد است
ولی اگر خیلی اصرار داری می تونی از تابع زیر استفاده کنی این تابع برگرفته از تابع ParsSQL در کلاس Paramerters است و فقط مقدار پارامترها را برای شما جایگزین کردم

function GetSQL(MyQuery:TADOQuery): string;
const
Literals = ['''', '"', '`'];
var
Value, CurPos, StartPos: PChar;
CurChar: Char;
Literal: Boolean;
EmbeddedLiteral: Boolean;
Name,MyParam,ResultSQL: string;
function NameDelimiter: Boolean;
begin
Result := CurChar in [' ', ',', ';', ')', #13, #10];
end;

function IsLiteral: Boolean;
begin
Result := CurChar in Literals;
end;

function StripLiterals(Buffer: PChar): string;
var
Len: Word;
TempBuf: PChar;

procedure StripChar;
begin
if TempBuf^ in Literals then
StrMove(TempBuf, TempBuf + 1, Len - 1);
if TempBuf[StrLen(TempBuf) - 1] in Literals then
TempBuf[StrLen(TempBuf) - 1] := #0;
end;

begin
Len := StrLen(Buffer) + 1;
TempBuf := AllocMem(Len);
Result := '';
try
StrCopy(TempBuf, Buffer);
StripChar;
Result := StrPas(TempBuf);
finally
FreeMem(TempBuf, Len);
end;
end;

begin
Result := MyQuery.SQL.Text;
ResultSQL:='';
Value := PChar(Result);
CurPos := Value;
Literal := False;
EmbeddedLiteral := False;
repeat
while (CurPos^ in LeadBytes) do Inc(CurPos, 2);
CurChar := CurPos^;
if CurChar <> #10 then
ResultSQL:=ResultSQL+CurChar
else
ResultSQL:=ResultSQL+#32;
if (CurChar = ':') and not Literal and ((CurPos + 1)^ <> ':') then
begin
StartPos := CurPos;
while (CurChar <> #0) and (Literal or not NameDelimiter) do
begin
Inc(CurPos);
while (CurPos^ in LeadBytes) do Inc(CurPos, 2);
CurChar := CurPos^;
if IsLiteral then
begin
Literal := Literal xor True;
if CurPos = StartPos + 1 then EmbeddedLiteral := True;
end;
end;
CurPos^ := #0;
if EmbeddedLiteral then
begin
Name := StripLiterals(StartPos + 1);
EmbeddedLiteral := False;
end
else Name := StrPas(StartPos + 1);


MyParam:=( MyQuery.Parameters.FindParam(Name).Value);
ResultSQL:=PChar(Copy(ResultSQL,1,Length(ResultSQL ) -1)+MyParam);

CurPos^ := CurChar;
StartPos^ := '?';

Inc(StartPos);

StrMove(StartPos, CurPos, StrLen(CurPos) + 1);
CurPos := StartPos;
end
else if (CurChar = ':') and not Literal and ((CurPos + 1)^ = ':') then
StrMove(CurPos, CurPos + 1, StrLen(CurPos) + 1)
else if IsLiteral then Literal := Literal xor True;
Inc(CurPos);
until CurChar = #0;
Result:=ResultSQL;

end;

حال ShowMessage را به صورت زیر فراخوانی کن
ShowMessage(GetSQL(qry1))
می توانی این تابع را در یک Unit ذخیره کنی و با ارسال Query مورد نظر به عنوان پارامتر آن نتیجه را همراه با مقادیر پارامترها ببینی
ولی فراموش نکنید که قبل از فراخوانی این تابع پارامترها را مقداردهی کرده باشید
خیلی نیازی نیست کار خود تابع را بدانی فقط همین که این تابع Query را گرفته و با پارس کردن متن SQL آن به صورت کارکتر به کارکتر هر گاه به علامت : برسد از آن نقطه به بعد تا تمام شدن شناسه آن را به عنوان یک پارامتر در نظر میگیرد و سپس مقدار پارامتر مورد نظر را از Query اصلی گرفته و جایگزین این پارامتر می کند

AmirSky
جمعه 12 خرداد 1391, 10:42 صبح
خیلی ممنون. همین رو میخواستم.:تشویق:
ولی نمی دونم چرا بعضی کارهای خیلی ساده که برنامه نویس اصلا نباید فکرش رو درگیر اونها کنه توی دلفی به این شکل حل میشه. تو محیط دلفی بعضی کارها مثل چرخوندن لقمه دور سره :متفکر:

همین کار توی php :



$name = 1000;
$sql = " SELECT * FROM tbl_animals WHERE name = $name ";
echo $sql;


در ضمن این تابع رو برای ذخیره کوئری ها در دیتابیس میخواستم

tiphooo
شنبه 13 خرداد 1391, 00:57 صبح
البته نمی شه با اینگونه موارد قیاس انجام داد و اگر نظر شخصی بنده را بخواهید دلفی برای هر چیزی حتما یک راه حل دارد و بعضی موارد اینچنینی به علت استفاده کم ترجیحا پوشش داده نشده اند

mohsen24000
شنبه 13 خرداد 1391, 08:50 صبح
این:

qry1.Sql.Text:='SELECT * FROM tbl_animals WHERE Title='+ IntToStr(X);
با


$name = 1000;$sql = " SELECT * FROM tbl_animals WHERE name = $name ";echo $sql;
فرقی نداشته و به عبارتی یکی است!