PDA

View Full Version : بهترین روش برای آپدیت بانک sql server 2008 ؟



programers0
جمعه 27 بهمن 1391, 00:12 صبح
با سلام
من یه برنامه نوشتم که مرتبا در حال تغییره و ممکنه مثلا امروز برم تغییراتو برای مشتری A انجام بدم و باز فردا برای مشتری B
حالا مشکل اینجاست که من نمیدونم این مشتری تا کجای کار بانکش درسته
مجبورم برم همرو به صورت دستی چک کنم و تغییرات رو اعمال کنم
این تغییرات ممکنه view ، stored procedure و ... باشه
بهترین روش برای حل این مشکل چیه که بتونم یه برنامه جدا واسه خودم بنویسم و همه تغییرات خودکار انجام بشه.
با تشکر

یوسف زالی
شنبه 28 بهمن 1391, 02:54 صبح
سلام
SQLDelta

programers0
شنبه 28 بهمن 1391, 19:35 عصر
میشه ببیشتر توضیح بدید؟

یوسف زالی
شنبه 28 بهمن 1391, 22:35 عصر
توضیح نداره. برنامه ای هست که می خوای.
گوگل کن همه چیزش می ریزه بیرون

benyaminrahimi
یک شنبه 29 بهمن 1391, 07:57 صبح
معمولا شرکت های نرم افزاری خودشون این قضیه رو مینویسن دو تا روش معمول و جود داره
1 یه دیتا بیس برای آخرین ورژن تهیه کنید و دیتا مشتری رو تیبل به تیبل به این دیتا بیس انتقال بدین (که تو دیتای زیاد مسایلی داره )
2 (روشی که من استفاده میکنم ) یه ماژول generate sqript بنویسید تو این روش در سیستم نرم افزاری تمام اجزا script میشن مثل table field view stored procedure function primary key ralation index و بعد با یک اسکریپ پاکسازی تمام object های مجازی رو پاک میکنید و sqript های generate sشده رو اجرا میکنید ui و script های این روشو برای فروش دارم اگه خواستین

samani
یک شنبه 29 بهمن 1391, 08:15 صبح
برنامه هايي مثل SQLDelta ، ApexSQLDiff و ... براي پيدا كردن تفاوت ساختار يا اطلاعات جداول خوبه به شكل دستي خوبه ، اما براي كنترل تغييرات برنامه در طي زمان بايد از روش ورژن بندي برنامه استفاده كنيد
يعني اينكه در هر تغيير بانك اطلاعاتي(ساختاري يا اطلاعاتي) ، تغييرات را به شكل اسكريپت براي هر ورژن در يك Query نگه داريد و هنگام اجراي برنامه اگر ورژن برنامه بزرگتر از ورژن بانك اطلاعاتي بود query مربوطه را اجرا ميكنيد و بعد از انجام عمليات و نداشتن خطا فيلد ورژني كه در بانك اطلاعاتي هست رو با عدد ورژن برنامه آپديت ميكنيد
اگر اسكريپت يك ورژن زياد بود داخل يك Query مثلا به نام qv2_12_1 ، اسكريپتها رو با دستور GO از هم جدا كنيد و از نمونه كد زير براي اسكريپت استفاده كنيد


unit Unit2;

interface

uses
SysUtils, Classes, Windows, strUtils, DB, ADODB;

type
TDMMain = class(TDataModule)
ADOConnection1: TADOConnection;
TVersion: TADOTable;
qv2_12_1: TADOQuery;
qv2_12_2: TADOQuery;
procedure DataModuleCreate(Sender: TObject);
private
function Run(ver: Integer): Boolean;
public
{ Public declarations }
end;

var
DMMain: TDMMain;

implementation

uses ADOInt;

{$R *.dfm}

function GetFileVer(var Major, Minor, Release, Build: word): boolean;
var
size, len: longword;
handle: THandle;
buffer: pchar;
pinfo: ^VS_FIXEDFILEINFO;
FileName: String;
begin
Result := False;

FileName := ParamStr(0);
size := GetFileVersionInfoSize(Pointer(FileName), handle);
if size > 0 then begin
GetMem(buffer, size);
if GetFileVersionInfo(Pointer(FileName), 0, size, buffer) then
if VerQueryValue(buffer, '\', pointer(pinfo), len) then begin
Major := HiWord(pinfo.dwFileVersionMS);
Minor := LoWord(pinfo.dwFileVersionMS);
Release := HiWord(pinfo.dwFileVersionLS);
Build := LoWord(pinfo.dwFileVersionLS);
Result := True;
end;
FreeMem(buffer);
end;
end;

function ExecuteScript(pScript: WideString): boolean;
var i, j: integer;
s: WideString;
sl: TStringList;
begin
Result := False;
if Trim(pScript) = '' then Exit;

sl := TStringList.Create;
try
pScript := #13#10'GO'#13#10 + pScript + #13#10'GO'#13#10;
i := 0;
repeat
j := PosEx(#13#10'GO'#13#10, UpperCase(pScript), i);
if (j >= i) and (j > 0) then
begin
s := Trim(Copy(pScript, i+1, j-i));
sl.Text := s;
while (sl.Count > 0) and (Trim(sl[0]) = #13#10) do
sl.Delete(0);

while (sl.Count > 0) and (Trim(sl[sl.Count-1]) = #13#10) do
sl.Delete(sl.Count-1);

s := Trim(sl.Text);

i := j + 4;
if (s <> '') and (UpperCase(s) <> 'GO') then
DMMain.ADOConnection1.Execute(Trim(s));
end;
until (j = 0) or (i = j);
Result := True;
finally
sl.Free;
end;
end;

function TDMMain.Run(ver: Integer): Boolean;
begin
Result := True;
try
case ver of
21201:
begin
ExecuteScript(qv2_12_1.SQL.Text);
end;
21202:
begin
ExecuteScript(qv2_12_2.SQL.Text);
end
else ;
end;
except on e: Exception do
begin
Result := False;
//log or showmessage(e.Message);
end;
end;
end;


procedure TDMMain.DataModuleCreate(Sender: TObject);
var
i: integer;
FileMajor, FileMinor, FileRelease, FileBuild: word;
dbMajor, dbMinor, dbRelease, dbBuild: word;
FullFileVer, FullDBVer: Integer;
f: boolean;
begin
TVersion.Open;
dbMajor := DMMain.TVersion.FieldByName('MajorVer').AsInteger;
dbMinor := DMMain.TVersion.FieldByName('MinorVer').AsInteger;
dbRelease := DMMain.TVersion.FieldByName('ReleaseVer').AsIntege r;
dbBuild := DMMain.TVersion.FieldByName('BuildVer').AsInteger;

FullDBVer := StrToIntDef(Format('%d%.2d%.2d', [dbMajor, dbMinor, dbRelease]), -1);
GetFileVer(FileMajor, FileMinor, FileRelease, FileBuild);
FullFileVer := StrToInt(Format('%d%.2d%.2d', [FileMajor, FileMinor, FileRelease]));

f := True; // f := BackupDB;
i := FullDBVer + 1;
while f and (i <= FullFileVer) do
begin
f := Run(i);
inc(i);
end;
if f and (FullFileVer > FullDBVer) then
DMMain.ADOConnection1.Execute('Update Version Set MajorVer = '+IntToStr(FileMajor)+', MinorVer = '+IntToStr(FileMinor)+', ReleaseVer = '+IntToStr(FileRelease)+', BuildVer = '+IntToStr(FileBuild));

end;

end.

یوسف زالی
یک شنبه 29 بهمن 1391, 10:23 صبح
مشکل اسکریبت اینه که داده های شما رو به خطر می ندازه.
فکر کنید اسکریبت یک جدول رو دوباره ران کنید...
دوستان، SQLDelta !

samani
یک شنبه 29 بهمن 1391, 10:41 صبح
تمام تغييرات هر ورژن بايد اتوماتيك انجام شود نه دستي

هر اسكريپت قبل از اجرا بايد در بانك اطلاعاتي چك شود اگر وجود نداشت اجرا ميشود براي مثال


if not exists (select * from dbo.sysobjects where id = object_id(N'dbo.Test') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
CREATE TABLE dbo.Test (
ID uniqueidentifier NOT NULL ,
f_ForeignKey uniqueidentifier NOT NULL
) ON [PRIMARY]
GO

IF NOT EXISTS (SELECT * FROM sysobjects where id = object_id(N'PK_Test') and OBJECTPROPERTY(id, N'IsConstraint') = 1)
ALTER TABLE dbo.Test WITH NOCHECK ADD CONSTRAINT PK_Test PRIMARY KEY CLUSTERED (ID) ON [PRIMARY]
GO

if not exists (select * from sysColumns where id = object_id(N'dbo.Test') and Name = 'Title')
ALTER TABLE Test ADD Title varchar(100) NULL
GO

UPDATE Test SET
Title = 'تست'
WHERE Title IS NULL
GO

benyaminrahimi
یک شنبه 29 بهمن 1391, 11:03 صبح
اگه پارامتر ها با not exists باشه مشکلی پیش نمیاد ... معلومه که تیبل دراپ نباید بشه منم نوشتم آبکت های مجازی که با دیتا کاری ندارند مثل view..

یوسف زالی
یک شنبه 29 بهمن 1391, 12:44 عصر
خب اون برنامه هم همین چک ها رو خودش انجام می ده.
اون برنامه این قابلیت ها رو داره:
انتخاب جدول - دیاگرام - ویو - استور - فانکشن - یوزر - رول - قانون - قید - دیفالت - کی - فیلد - سینونیم ...
قابلیت نمایش متنی که در استور متفاوته
قابلیت انتخاب بخشی از تغییرات برای سینک شدن
قابلیت فیلتر کردن آبجکت ها
.
.
حالا اصرار برای دستی انجام دادنش ممکنه یک کم "اختراع مجدد چرخ" باشه

benyaminrahimi
یک شنبه 29 بهمن 1391, 13:43 عصر
بعضی مواقع ترییب SQRIPT مهمه یا مسایل دیگه ... که وقتی تو این مورد خاص کد میزنی دست خودته.. همون کاری که sql data کرده ولی تظمینی نیست که تو همه مسایلی که تو میخای جواب بده .. وگرنه این چیزایی که شوما نوشتینم با قابلیت فیلتر!!!!! خود SQL SERVER داره پس این برنامه هم چرخو مجددا اختراع کرده ؟ ............. منظور از دستی انجام دادنشو نفهمیدم

یوسف زالی
یک شنبه 29 بهمن 1391, 14:02 عصر
:)))
فیلتر تعجب نداره!
دستی Generate کردن Script منظور منه.
SQL Server میاد دو تا StoredProc رو مقایسه کنه و بگه کجاهاش متفاوته؟
واقعا؟!
عجب...

benyaminrahimi
یک شنبه 29 بهمن 1391, 14:17 عصر
نه اینایی که شوما نوشتی گفتم آخه رو فیلتر کردن خیلی مانور داده بودین (قابلیت ) که sql داره اینارو

اون برنامه این قابلیت ها رو داره:
انتخاب جدول - دیاگرام - ویو - استور - فانکشن - یوزر - رول - قانون - قید - دیفالت - کی - فیلد - سینونیم ...
قابلیت نمایش متنی که در استور متفاوته
قابلیت انتخاب بخشی از تغییرات برای سینک شدن
قابلیت فیلتر کردن آبجکت ها

مقایسه و فهمیدن اختلاف دو پروسیجر تو ورژنیگ زیاد مهم نیست ... تو check in کردن برنامه نویسا مهمه

من برای اینکه ساده تر بگم یه نمونه کدای تغییرات جدولمو میذارم که خیلی راحته و با برنامه خودم در عرض 2 ثانیه اسکریپت میده


IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE id = object_id(N'[tempdb].[dbo].[#tblSQL]'))
DROP TABLE [dbo].[#tblSQL]

CREATE TABLE #tblSQL
(
sc VARCHAR(max) NOT NULL

)



INSERT INTO #tblSQL
(
sc
)



SELECT
'IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'+''''+'[dbo].[' +
so.name ++ ']'+''''+') AND type in (' + '''U'''
+ ')) begin create table [' + so.name + '] (' + o.list + ')' + CASE
WHEN
tc.Constraint_Name
IS
NULL THEN
''
ELSE
'ALTER TABLE ['
+
so.Name
+
'] ADD CONSTRAINT ['
+
tc.Constraint_Name
+
'] PRIMARY KEY '
+
' ('
+
LEFT(j.List, LEN(j.List) - 1)
+
') '

END+' end ' AS tbl_sc
FROM sysobjects so
CROSS APPLY
(
SELECT ' [' + column_name + '] ' +
data_type + CASE data_type
WHEN 'sql_variant' THEN ''

WHEN 'text' THEN ''
WHEN 'IMAGE' THEN ''
WHEN 'decimal' THEN '(' + CAST(numeric_precision_radix AS VARCHAR)
+ ', ' + CAST(numeric_scale AS VARCHAR) + ')'
ELSE COALESCE(
'(' + CASE
WHEN character_maximum_length =
-1 THEN 'MAX'
ELSE CAST(character_maximum_length AS VARCHAR)
END + ')',
''
)
END + ' ' +
CASE
WHEN EXISTS (
SELECT id
FROM syscolumns
WHERE OBJECT_NAME(id) = so.name
AND NAME = column_name
AND COLUMNPROPERTY(id, NAME, 'IsIdentity') = 1
) THEN 'IDENTITY(' +
CAST(IDENT_SEED(so.name) AS VARCHAR) + ',' +
CAST(IDENT_INCR(so.name) AS VARCHAR) + ')'
ELSE ''
END + ' ' + (CASE WHEN IS_NULLABLE = 'No' THEN 'NOT ' ELSE '' END) +
'NULL ' +
CASE
WHEN information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN
'DEFAULT ' + information_schema.columns.COLUMN_DEFAULT
ELSE ''
END + ', '
FROM information_schema.columns
WHERE table_name = so.name
ORDER BY
ordinal_position
FOR XML PATH('')
) o(list)
LEFT JOIN information_schema.table_constraints tc
ON tc.Table_name = so.Name
AND tc.Constraint_Type = 'PRIMARY KEY '
CROSS APPLY
(
SELECT '[' + Column_Name + '], '
FROM information_schema.key_column_usage kcu
WHERE kcu.Constraint_Name = tc.Constraint_Name
ORDER BY
ORDINAL_POSITION
FOR XML PATH('')
)


j(list)
WHERE xtype = 'U'
AND NAME NOT IN ('dtproperties')


SELECT * FROM #tblSQL

یوسف زالی
یک شنبه 29 بهمن 1391, 19:55 عصر
مانور؟!
بین اون همه پیامبر جرجیس رو مثال می زنی؟!
برای من مهمه که چرا اختلاف وجود داره.
نظر شما هم محترم. موفق باشید.