C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

стр.: (2) < 1 [2] >
Копирование строк из Грида в таблицу БД
laifik
Отправлено: 28.01.2005, 11:12


Дежурный стрелочник

Группа: Участник
Сообщений: 70



Я тут пытаюсь почерпнуть полезное из всех вариантов, что у меня есть. Получилось вот что:
CODE
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (DBGridEh2->SelectedRows->Count == 0) return;

TADOCommand *cmd = ADOCommand2;
cmd->ParamCheck  = true;
cmd->Prepared    = false;

cmd->CommandText = "Drop table dbo.Load_Bookmark";
try        { cmd->Execute(); }
catch(...) {;               }

String TableName = "Load_Bookmark";  
TADOQuery *qry = ADOBookmark;

qry->ParamCheck  = true;
qry->Prepared    = false;

qry->SQL->Text = "CREATE TABLE dbo." + TableName + " (CardID int, KodSyst int, \
GostID char (14), Project_Def char (10), NameRD char (250),  Gruppa char (10), Nomer char (6), \
Sapis int, Massa real, PlechoX real, PlechoY real, PlechoZ real, \
Department char (3), DataSapoln datetime, Prim char (400), Slujebn ntext, \
dmhP real, Prozent real, Developer char (20), Mx_R float, My_R float, Mz_R float, ImageArh int)";
qry->ExecSQL();

   AnsiString Misc="",s = "";
   TDataSet *pDS = DBGridEh2->DataSource->DataSet;
   for (int i=0; i < DBGridEh2->SelectedRows->Count; i++)
   {
     pDS->GotoBookmark((void *)DBGridEh2->SelectedRows->Items[i].c_str());
     for(int j=0;j<pDS->FieldCount;j++)
      {TField* Fl=pDS->Fields->Fields[j];
       if (j)
        {
         Misc=Misc+","+Fl->FieldName;
         s =s+",:P"+Fl->FieldName;
        }
        else
        {
          Misc="insert into dbo.Load_Bookmark ("+Fl->FieldName;
          s ="values (:P"+Fl->FieldName;
        }
       }
       Misc=Misc+")";
       s=s+")";
     qry->SQL->Clear();
     qry->SQL->Add(Misc);
     qry->SQL->Add(s);

     qry->Parameters->ParseSQL(qry->SQL->Text,true);
     for(int k=0;k<pDS->FieldCount;k++)
      {TField* FP=pDS->Fields->Fields[k];
       qry->Parameters->Items[k]->Value=FP->Value;
         //  ShowMessage(FP->Value);
      }
     qry->ExecSQL();
   }
}

Код заработал. Оказывается, нужно было выставить формат числовых полей, например "0.00".
А вот datetime не пропускает. Пробовала подставлять разные форматы даты/времени. Даже в самом Гриде (в свойствах полей). Не получается.
Например, в Гриде отображается "28 января 2005 г.", а если просмотреть переменную ShowMessage(FP->Value);, то она будет в таком формате "28.01.2005 15:54:30". Идет постоянная ссылка на ODBC SQL Server Driever, на какую-то нереализованную возможность. Отладка ничего не дает.
Не подскажите, что с этим делать?
avc*
Отправлено: 28.01.2005, 12:23


Не зарегистрирован







Я ни как не пойму вашаго настойчивого стремления перегенерировать текст запроса с каждой новой строкой ohmy.gif . Ну это так к слову.

Раз не удается победить драйвер для правильной передачи параметров (я с таким просто ни когда не сталкивался). То вам подойдет тот вариант, который я не стал расписывать в своем примере. Для его реализации мне нужно точно знать как записываются константы разных типов в MySQL.
Поправьте строку value следующего оператора так, что бы он работал правильно
Insert int aaa (Char_Field, Integer_Field, Float_Field, Real_Field, NText_Field, DateTime_Field)
Values ('char', 0, 0.00, 0.00, ???, '28.01.2005 11:20:01')

Кстати, если ТNText это Blob то параметры — почти единственное решение.

PS. А варант через PK чем не устраивает?

PPS. В приведенном вами коде ADOCommand2 можно (и нужно) заменить на ADOBookmark — они выполняют одинаковые функции. В примере ADOCommand использовался просто для наглядности.
laifik
Отправлено: 28.01.2005, 13:37


Дежурный стрелочник

Группа: Участник
Сообщений: 70



QUOTE (avc* @ 28/01/2005, 13:25)
Я ни как не пойму вашаго настойчивого стремления перегенерировать текст запроса с каждой новой строкой

Это единственный вариант, который работает (без datetime). С этим вопросом я вожусь пятый день, такого никогда не было. Это очень задерживает работу. Но вопрос очень важный. Чтобы решить его самостоятельно, не хватает знаний.

QUOTE
Поправьте строку value следующего оператора так, что бы он работал правильно
Insert int aaa (Char_Field, Integer_Field, Float_Field, Real_Field, NText_Field, DateTime_Field)
Values ('char',  0,  0.00,  0.00,  ???,  '28.01.2005 11:20:01')

А как это сделать?
QUOTE
А варант через PK чем не устраивает?

Устроил бы, если бы смогла подцепить базу My SQL и посмотреть, как код работает для моих таблиц. Но ... не получается. Да, и переключилась на код, который наполовину работает. Если бы не сроки, с удовольствием бы покопалась во всех кодах.

Отредактировано laifik — 28/01/2005, 14:39
AVC
Отправлено: 28.01.2005, 14:04


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE
Это единственный вариант, который работает

"Все страньше и страньше" как говорила Алиса.

QUOTE
А как это сделать?

В строке values написать примеры "правильных" констант. Правильные это те которые поймет драйвер и сервер. Экспериментировать можно в каком либо редакторе SQL.
Очень нужны ответа на
что такое NText
можно ли константу real писать 1.23 или нужна запятая, аналогично для float
как правильно написать константу datetime
для поля datatime нужна только дата или дата и время.

Например для сегодняшнего (28.01.2005) числа поля datetime в разных СУБД можно писать так (а еще зависит от настроек системы и сервера)
Access #01/28/2004#
Sybase '20050128'
Oracle '28.01.2005'


QUOTE
если бы смогла подцепить базу My SQL ...

Если подойти чисто формально — сетка связана с таблицей или запросом.
Предположим, что поле "CardID" обладает свойствами первичного ключа для данной выборки.
Запрос на вставку должен выглядеть так
Insert into dbo.insert into dbo.Load_Bookmark +
Если источник данных сетки таблица тогда
Select * From таблица_источник Where CardIN in (...)
Если источник данных для сетки запрос то нужно дополнить условия выборки условием CardID in (...)
Или, если позволяет синтаксис, Select * From ("текст_запроса_из_источника_сетки") t1 Where t1.CardIN in (...)

Как видите лезть в сервер в этом случае не надо.
laifik
Отправлено: 28.01.2005, 14:58


Дежурный стрелочник

Группа: Участник
Сообщений: 70



У-ра-ра! biggrin.gif
Вариант с PK получился. И оказался он не сложным. Просто я уже устала от разборки этого вопроса и мысли в "раскоряку" от обилия вариантов.
А в предыдущем варианте так и не поняла, что нужно сделать с полем datetime?

QUOTE
что такое NText
 — это Memo поле.
QUOTE
можно ли константу real писать 1.23 или нужна запятая, аналогично для float

Желательно с запятой
QUOTE
для поля datatime нужна только дата или дата и время.

Нужна только дата
QUOTE
В строке values написать примеры "правильных" констант

А как это написать?
AVC
Отправлено: 28.01.2005, 15:33


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE

У-ра-ра!  
Вариант с PK получился. И оказался он не сложным.

Поздравляю. smile.gif Это мой любимый вариант.

QUOTE
 
QUOTE
В строке values написать примеры "правильных" констант

А как это написать?

Я хотел добиться примерно такого:
CREATE TABLE OldTable
(OldTableID INTEGER(8) NOT NULL UNIQUE
,OldTable_Name CHAR(40)
,FDateTime DATETIME
,FFloat` FLOAT(18,8)
,PRIMARY KEY (OldTableID));

Insert into OldTable (OldTableID, OldTable_Name, FDateTime, FFloat)
Select
Max(OldTableID) + 1
,Concat(Max(OldTableID) + 1, '-aaa')
,'2005-01-22 13:44' -- вот этого !!!!!!!!!
,13.45 -- и этого !!!!!!!!!!
From OldTable

Нашел развернутый MySQL, но не могу соединиться через ADO — не знаю пароля, а хозяин в другом городе.
Теперь это уже не важно.

Удачи ! biggrin.gif
laifik
Отправлено: 28.01.2005, 15:56


Дежурный стрелочник

Группа: Участник
Сообщений: 70



Огромное спасибо за помощь! smile.gif
Попробую все-таки добить другой вариант (чтобы понять, что происходит). Может, на свежую голову лучше пойдет?
А в программе использую вариант с PK. Он прост и красив.
AVC
Отправлено: 28.01.2005, 17:21


Ветеран

Группа: Модератор
Сообщений: 1583



Посмотрел по Helpy — можно выполнить хорошую модификацию варианта с PK если переписать запрос так

Create Table новая_таблица As
Select t.*
From (текст_запроса_источника_сетки) t
Where t.CardID in (список_значений_поля_CardID)

При этом отпадает необходимость "ручного" создания таблицы. Предварительно нежно удалить 'новая_таблица'.
Предупреждение о максимальном числе значений в конструкции IN остается в силе.

Отредактировано AVC — 28/01/2005, 17:24
стр.: (2) < 1 [2] >
Вернуться в Вопросы программирования в C++Builder