Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как проверить что в базе есть таблица?


Страницы:   1 2

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

Читаю, но имхо подход с версией гораздо правильнее…


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо