![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как проверить что в базе есть таблица?
Kolan © (2007-12-19 17:16:00)Здравствуйте,
Работаю с MS SQL Server 2000.
Допустим мне надо выполнить запрос:
SQL.Add('SELECT * FROM CONF_USER');
Как проверить есть ли таблица CONF_USER?
И вообще, как бы организовать проверку что схема базы соответствует нужной программе?
ЗЫ
Можно конечно достать из системных таблиц, но ведь это не всегда возможно, или вседа?
Ega23 (2007-12-23 14:18:00) [1]Для таблицы :
if exists (select 1 from sysobjects where id = object_id('TableName') and type = 'U')
Для поля :
if COLUMNPROPERTY(OBJECT_ID(N'[TableName]'), 'columnName', 'precision') is NULL
begin
ALTER TABLE TableName add columnName .... ;
MsGuns (2007-12-22 19:39:00) [2]Забыл ;)
RSQLServerVersion = record
VersNum: string;
ModNum: string;
end;
MsGuns (2007-12-22 19:35:00) [3]
type
// Дескриптор SQL-сервера
PMSSQLServerDef = ^RMSSQLServerDef;
RMSSQLServerDef = record
ServerName: string; // Имя сервера
InstanceName: string; // Установочный ид-р сервера
IsClustered: boolean; // Флаг включения в серверный кластер
Version: RSQLServerVersion; // Версия сервера
Port: integer; // Коммуникационный порт
Path: string; // Путь к серверу в сети
end;
// Дескриптор SQL колонки (поля)
PSQLFieldDef = ^RSQLFieldDef;
RSQLFieldDef = record
FldName: string;
PKey: boolean;
AInc: boolean;
IsNULL: boolean;
FldType: string;
FType: TFieldType;
Length: word;
Scale: byte;
Description: string;
end;
function SQLServ_GetServerTableList(SQLServer: PMSSQLServerDef; DataBase: string; ListTables: TStrings): boolean;
begin
ListTables.Clear;
with TADODataSet.Create(nil) do
try
ConnectionString := 'Provider=SQLOLEDB;'+
';Persist Security Info=false'+
';User ID=sa'+
';Data Source='+SQLServer.ServerName;
CommandText := 'use '+DataBase+' select * from sysobjects where xtype='+QuotedStr('u');
try
Open;
while not eof do
begin
ListTables.Add(Fields[0].AsString);
Next;
end;
Close;
result := true;
except
result := false;
end;
finally
Free;
end;
end;
function SQLServ_GetTableFieldsList(SQLServer: PMSSQLServerDef; DataBase,TableName: string; ListFields: TList): boolean;
var
i: integer;
fd: PSQLFieldDef;
begin
for i := 0 to ListFields.Count-1 do Dispose(PSQLFieldDef(ListFields[i]));
ListFields.Clear;
with TADODataSet.Create(nil) do
try
ConnectionString := 'Provider=SQLOLEDB;'+
';Persist Security Info=false'+
';User ID=sa'+
';Data Source='+SQLServer.ServerName;
CommandText := 'use '+DataBase+' Exec sp_columns '+TableName;
Open;
while not EOF do
begin
fd := NEW(PSQLFieldDef);
fd.FldName := FieldByName('COLUMN_NAME').AsString;
fd.PKey := false;
fd.FldType := FieldByName('TYPE_NAME').AsString;
fd.AInc := (Pos('IDENTITY',UpperCase(fd.FldType))>0);
fd.IsNULL := (FieldByName('IS_NULLABLE').AsString='YES');
fd.Length := StrToInt(FieldByName('LENGTH').AsString);
fd.Scale := 0;
if UpperCase(fd.FldType)='NUMERIC' then
fd.Scale := StrToInt(FieldByName('SCALE').AsString);
fd.Description := 'No Description';
ListFields.Add(fd);
Next;
end;
Close;
// Извлечение описателей
CommandText := 'use '+DataBase+' select sc.name, sp.value '+
'from sysobjects so, syscolumns sc, sysproperties sp '+
'where so.id=sc.id and so.id=sp.id and '+
'sp.smallid=sc.colorder and so.name='+QuotedStr(TableName);
Open;
for i := 0 to ListFields.Count-1 do
if Locate(Fields[0].FieldName,PSQLFieldDef(ListFields[i]).FldName,[]) then
PSQLFieldDef(ListFields[i]).Description := Fields[1].AsString;
Close;
result := true;
finally
Free;
end;
end;
Kolan (2007-12-21 16:04:00) [4]Сделал
select * from syscolumns where id=OBJECT_ID('таблица') and name='поле'
Palladin (2007-12-21 14:34:00) [5]бежать придется по FildDefs, Fields'ов не будет, бо не будет курсора, это раз, два - гораздо легковесней выполнить TADOConnection.GetFieldNames
Плохиш (2007-12-21 14:32:00) [6]2.1. Запрос select * from таблица where 1=0
2.2. Пробежаться по Fields/FieldDefs
Kolan (2007-12-21 14:23:00) [7]> ну в теории должно всегда по крайней мере у меня проблем
> не было
ок
Palladin (2007-12-21 14:20:00) [8]ну в теории должно всегда... по крайней мере у меня проблем не было
Kolan (2007-12-21 14:15:00) [9]> select * from syscolumns where id=OBJECT_ID('таблица') and
> name='поле'
А всегда это получится? Права доступа не повлияют?
Palladin (2007-12-21 14:13:00) [10]select * from syscolumns where id=OBJECT_ID('таблица') and name='поле'
Kolan (2007-12-21 14:07:00) [11]Вот как правильно сделат пункт 2 я незнаю …
COL_NAME наверно?
Kolan (2007-12-21 13:58:00) [12]Тааак, продолжаем разговор.
1. В бд есть таблица в которой есть поля для версии.
MajorVersion
MinorVersion
ReleaseVersion
BuildVersion
Хоть таблица и была раньше никакой софт версию не проверял почему-то
2. Теперь в эту таблицу добавили поле Type тип бд. Но по административным причинам это поле может и отсутствовать.
Итог алгоритм проверки такой:
1. Проверяю что есть нужная таблица
if OBJECT_ID() is not null
2. Если она есть, то проверяю есть ли там нужные поля(так как Type может не быть).
3. Если есть, то сравниваю тип и версию
В случае неудачь понятно матерюсь
Вот как правильно сделат пункт 2 я незнаю
Petr V. Abramov (2007-12-19 22:49:00) [13]> Kolan © (19.12.07 22:30) [14]
> От это сложнее диалог та внедрах винды…
а файерволл - в руках админа.
проще, чем то, что ты задумал.
Kolan (2007-12-19 22:30:00) [14]> 1. ограничить выбор доступных баз «правильными»
От это сложнее диалог та внедрах винды
Petr V. Abramov (2007-12-19 21:57:00) [15]> эксепшены invalid object …
для бестолкового что "invalid object …", что "глубокоуважаемый, Вы подключились к хранилищу данных, где того, что Вы хотите, просто нет" -
КОМПЬЮТЕР НЕ РАБОТАЕТ!!!
Petr V. Abramov (2007-12-19 21:54:00) [16]> а потом если перепутали базу,
а если перепутали, куда пришли? А если голову забыли?
решаемо, конечно, все, но:
1. ограничить выбор доступных баз "правильными"
2. довести до сознания, что если есть возможность коннекта к, допустим, тестовой и боевой, в них есть несоответствия и они выражаются как "ачинаются эксепшены invalid object …"
3. кто 2. не понимает - бестолковый тестер
Kolan (2007-12-19 18:53:00) [17]> И потом проверять, есть ли в базе служебная таблица ;)
Угу, только не потом, а сначала. Тут и пригодитсяGetTableNamesилиOBJECT_ID.
DiamondShark (2007-12-19 18:07:00) [18]
> В БД надо сделать служебную таблицу где писать тип БД.
И потом проверять, есть ли в базе служебная таблица ;)
DiamondShark (2007-12-19 18:06:00) [19]
> Как проверить есть ли таблица CONF_USER?
if OBJECT_ID('CONF_USER') is not null
Kolan (2007-12-19 17:53:00) [20]> TAdoConnection.GetTableNames
Читаю, но имхо подход с версией гораздо правильнее