Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

С чего начать изучение SQL

18K
14 декабря 2010 года
imAlex
179 / / 29.07.2010
Доброе время суток.
Я хочу научиться создавать и работать с базами, но вот не задачка: "С чего начать?". Подскажите что проще в освоении MS SQL или MSQL. Может кто знает умные статьи для чайников?
У меня есть программа, написанная мной на С. Она по сути отслеживает приход/уход сотрудников, если пользователь ничего не делает в течении n-ного кол. времени то фиксирует и это. Сейчас прога создает текстовый файл, дальше средствами JS и php я это обрабатываю и вывожу на сайт. Хотелось бы все это в базу. Соответственно какая база лучше?
Страницы:
8
29 декабря 2010 года
mfender
3.5K / / 15.06.2005
Цитата: SomewherSomehow
Я про то, что чтобы манипулирвоать данными, не нужно все разнообразие функций что специфично для каждой субд, нужен только механизм сообщения клиента и сервера, с этой ролью одбц прекрасно справляется.


Ну так этому наверное и в школе уже учат. )))) Для тех, кому достаточно DBTable и DBNavigator - ODBC самое оно! А вот в случае, как вы заметили…

Цитата:
Сформировали вы на клиенте запрос, само собой в синтаксисе мускуля, но вам же надо как-то его отдать серверу и получить результаты... как будете действовать?


…всё куда сложнее. Тут никакой ODBC не поможет. Нужно рисовать более конкретно, потому что SQL не имеет абстракций.

Насчёт «как» - это вопрос решаемый. Сами понимаете, связаться с чем угодно можно как угодно, причём всё зависит от степени подготовленности связующегося: кому-то ниже сокетов гораздо, кому-то сокеты подавай, а такие ленивые как я начинают юзать Indy по разным протоколам. :D

385
29 декабря 2010 года
SomewherSomehow
477 / / 25.07.2004
Цитата: mfender
Тут никакой ODBC не поможет. Нужно рисовать более конкретно, потому что SQL не имеет абстракций.

Да нет, как раз поможет и абстракции тут ни при чем.
Впрочем ладно, топик все-таки не об этом. Думаю ТС получил исчерпывающие сведение про то как соединяться :D
к тому же судя по всему это уже не актуально
[QUOTE=imAlex] Связь программы и базы я уже установил, пробую посылать запросы.[/QUOTE] так что заканчваем флеймить.

8
29 декабря 2010 года
mfender
3.5K / / 15.06.2005
можно побоище устроить в отдельной топе, а потом продолжить физически за кругалём хмельного :D
18K
30 декабря 2010 года
imAlex
179 / / 29.07.2010
Цитата: SomewherSomehow
так что заканчиваем флеймить.


С интересом читал все ваши сообщения, подчеркнул для себя много важного. По поводу ваших дебатов, я в этом пока не разбираюсь, не мне судить, но на тему ответ вразумительный и раскрытый уже получен. Огромное спасибо.
На данном этапе я пытаюсь посылать различные запросы, пока не все получается.
По поводу закрытия темы, не знаю. Мне либо новую создать в разделе С++, либо здесь продолжить про SQL + C++.

8
30 декабря 2010 года
mfender
3.5K / / 15.06.2005
Нет, если про базы данных, то в этом разделе. C++ это как-то мало касается.

Так на какую СУБД пал выбор? )))))
18K
30 декабря 2010 года
imAlex
179 / / 29.07.2010
Я создал таблицу запросом
 
Код:
CREATE TABLE
        `db_users` (
            `id` INT(11) NOT NULL AUTO_INCREMENT,
            `login` CHAR(30) NOT NULL,
            PRIMARY KEY(`id`)
        )

добавляю в нее строку
 
Код:
INSERT INTO `db_users` (`login`) VALUES ('test')

получил id=1, ligin=test. Удалил строку из MyAdmin. Добавил заново и у меня почему то id=2, а не 1. Почему так, и как это исправить?
5
30 декабря 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: imAlex
Я создал таблицу запросом
 
Код:
CREATE TABLE
        `db_users` (
            `id` INT(11) NOT NULL AUTO_INCREMENT,
            `login` CHAR(30) NOT NULL,
            PRIMARY KEY(`id`)
        )

добавляю в нее строку
 
Код:
INSERT INTO `db_users` (`login`) VALUES ('test')

получил id=1, ligin=test. Удалил строку из MyAdmin. Добавил заново и у меня почему то id=2, а не 1. Почему так, и как это исправить?


Ключевое слово выделено жирным.
Добавление новой записи в эту таблицу увеличивает внутренний счетчик, следующее значение которого записывается в поле id.

18K
30 декабря 2010 года
imAlex
179 / / 29.07.2010
Логично. В принципе мне в данной таблице надо, чтоб так и было.
Я тут просто вычитал, что нельзя поменять только одно значение в строке. Допустим: есть строку 1,1,2,1,date (каждое значение-это столбец одной строки), и мне необходимо значение "date" изменить, допустим, на "30_12_2010". Как пишут, необходимо полностью переписать строку. При этом у меня поменяется id.
5
30 декабря 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: imAlex

Я тут просто вычитал, что нельзя поменять только одно значение в строке.


Выбрасывайте в мусорку что читали. DML операторы работают над множествами:

 
Код:
UPDATE table1
SET date = '30_12_2010'
WHERE id = 10

поле date будет обновлено во всех строках отвечающих условию WHERE.
18K
30 декабря 2010 года
imAlex
179 / / 29.07.2010
Нашел. Можно обновить значение с помощью
 
Код:
INSERT INTO `db_pcname` (`pcname`) VALUES ('OK6-PC1')

Искал, как узнать значение поля по id, а нашел как поменять значение
18K
30 декабря 2010 года
imAlex
179 / / 29.07.2010
не успел. Пасибо
18K
30 декабря 2010 года
imAlex
179 / / 29.07.2010
Никак не получается получить значение. Пишу:
 
Код:
char temp;
temp=mysql_query(&conn,"SELECT * FROM db_pcname WHERE (id='1') ORDER BY pcname");

возвращает 0, а там "TEST"
Что я делаю не правильно? (VC C++, библиотека mysqk.h) Может запрос не правильный?
18K
30 декабря 2010 года
imAlex
179 / / 29.07.2010
Так:
 
Код:
mysql_query(&conn, "SELECT * FROM bd_pcname WHERE (id='1')");
    MYSQL_RES* result = mysql_store_result(&conn);
    MYSQL_ROW row = mysql_fetch_row(result);
    row[0];

возвращает 1.
8
30 декабря 2010 года
mfender
3.5K / / 15.06.2005
Цитата: imAlex
Никак не получается получить значение. Пишу:
 
Код:
char temp;
temp=mysql_query(&conn,"SELECT * FROM db_pcname WHERE (id='1') ORDER BY pcname");
возвращает 0, а там "TEST"
Что я делаю не правильно? (VC C++, библиотека mysqk.h) Может запрос не правильный?


Убери скобки и кавычки для интересу. У тебя в WHERE всего один параметр задан, а скобки в SQL несут несколько иную функцию и где ни попадя ими пользоваться не стоит. И кавычки, вроде как не мешают, но ты же знаешь, что поле db_pcname - INTEGER. Для него кавычек вообще не надо.

Да, и самое главное: mysql_query возвращает FALSE, если ошибка, и хандлер запроса, если он что-то сделал. Результаты запроса, как ты понял, немного не там находятся.

18K
11 января 2011 года
imAlex
179 / / 29.07.2010
Цитата:
Да, и самое главное: mysql_query возвращает FALSE, если ошибка, и хандлер запроса, если он что-то сделал. Результаты запроса, как ты понял, немного не там находятся.


А куда он тогда возвращает результат?

8
11 января 2011 года
mfender
3.5K / / 15.06.2005
Цитата: imAlex
А куда он тогда возвращает результат?


Если тебя интересует этот вопрос, есть очень много литературы по кишкам CУБД. Но в данном случае не это должно тебя волновать.

Результат запроса физически где-то там, и получить его можно с помощью различных функций: mysql_fetch_array, mysql_fetch_assoc et cetera.

18K
11 января 2011 года
imAlex
179 / / 29.07.2010
Понятно.
Я получил результат сл. образом:
Код:
mysql_query(&conn, "SELECT time_out FROM time_in_out WHERE (id_login='1') AND (date='2010-12-20')");


    if ((res = mysql_store_result(&conn)))
    {
        while((row = mysql_fetch_row(res)))
        {
            for (j=0 ; j < mysql_num_fields(res); j++)
            printf("%s\n",row[j]);
        }
    }

про "mysql_fetch_array, mysql_fetch_assoc et cetera" почитаю.
18K
11 января 2011 года
imAlex
179 / / 29.07.2010
А как можно организовать счетчик в базе.
Т.е.: хочу добавить колонку "№сессии". Ее начальное значение например 1.
Дальше в течении дня идет работа с базой, и в какой то момент необходимо добавить к имеющемуся значению 1.
Другими словами, пользователь ВКЛ ПК (в таблицу записалось: логин, имя ПК, дата, time_in, time_out{текущее время}, №сессии=1), работает,.. в базу через каждую минуту падает время в графу time_out. Потом пользователь ВЫК ПК. Погулял часок, вернулся и ВКЛ ПК. №сессии прибавился и тд.

Обращаю внимание на тот факт, что не при каждом обращении к строке таблицы, а лишь по некому запросу должен срабатывать счетчик.

У меня есть сл. вариант алгоритма: при необходимости читать значение ячейки, прибавлять 1 и переписывать его. Но т.к. это будет делать прога, придется читать>переводить в int>считать(+1)>перезаписывать.

Может есть вариант в стиле послал запрос, а sql прибавил 1? )))
8
11 января 2011 года
mfender
3.5K / / 15.06.2005
UPDATE table_name
SET field_name = field_name + 1
WHERE id = <что-то там>
18K
11 января 2011 года
imAlex
179 / / 29.07.2010
пасибо. А если с временем? Например есть графы: time_in, time_uot, time_summ. В time_summ должна быть сумма пред идущих.
Или необходимо достать значения из них и только потом отослать на сумму?
18K
11 января 2011 года
imAlex
179 / / 29.07.2010
Цитата:
UPDATE users
SET time_summ = time_out - time_in
WHERE id = 1


Работает. Чудеса, да и только )))

18K
11 января 2011 года
imAlex
179 / / 29.07.2010
Блин. У меня прога почему то память ест, примерно 100kb/min. Никак не пойму почему. Кто сталкивался с такой проблемой? Могу код выложить, если надо.
Я сначала думал, может где резервирую постоянно, но нет.
Принцип работы:
запускаем->соединяемся с базой->проверяем, имеется ли запись(если да, то изменяем два параметра, иначе создаем запись)->дальше через каждую минуту изменяем 1 значение в одной таблице.
И что здесь может память кушать?

Может это как то связано с предупреждением компилятора?
Цитата:
c:\program files\microsoft sdks\windows\v7.0a\include\mysql_com.h(28): warning C4005: USERNAME_LENGTH: изменение макроопределения
1> c:\program files\microsoft sdks\windows\v7.0a\include\wtsapi32.h(55): см. предыдущее определение "USERNAME_LENGTH"

18K
11 января 2011 года
imAlex
179 / / 29.07.2010
Вот задался еще одним вопросом:
Есть таблица с полями id, id_s, time_lock, time_unlock, summ_time. Первое значение-id в данной таблице, id_s -это id в таблице прихода/ухода, time_lock и time_unlock время блокировки и раз блокировки, последнее-сумма пред идущих.
Есть другая таблица с полями id, id_s, time. Как можно сделать так, чтоб при появлении новой строки, или изменении старой строки в первой таблице, изменялись значения во второй, которая является результатом сложения всех полей summ_time с данным id_s? То есть сумма всех значения summ_time с id_s из первой таблицы=time с id_s во второй.
Можно ли это сделать на автомате?
7
11 января 2011 года
@pixo $oft
3.4K / / 20.09.2006
Цитата: imAlex
Может это как то связано с предупреждением компилятора?

Да связано,конечно!:) Посмотрите на код в указанных строках.Очень может быть,что из-за изменения макроопределения память будет утекать,ибо хз что делает изменённый код

18K
12 января 2011 года
imAlex
179 / / 29.07.2010
В mysql_com.h
 
Код:
#define USERNAME_LENGTH         (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN)

в wtsapi32.h
 
Код:
#define USERNAME_LENGTH          20

Вторая библиотека мне нужна для регистрации сессии:
 
Код:
WTSUnRegisterSessionNotification
18K
12 января 2011 года
imAlex
179 / / 29.07.2010
Я попробовал закоментить строчку в mysql_com.h. Память стала утекать медленней. Утекает только при запросе в базу UPDATE... причем со следующей зависимостью: 32, 20, 16, 36, 20, 24... с периодичностью ровно одна минута.
Ниже код:
Код:
void logout(void* pParams)
{      

    while (1)
    {
        conn_db();
        _strtime_s(timeStr);
        sprintf_s(update,"time_out='%s'",timeStr);
        sprintf_s(update_id,"id='%s'",id_inOut);
        update_db ("time_in_out", update, update_id);
        Sleep(60000);
    }
}

Код:
int update_db (char* table, char* what, char* wher)//замена значения
{
    conn_db();
    sprintf_s(buff, "UPDATE %s SET %s WHERE (%s)", table, what, wher);
    if (!mysql_query(&conn,buff))
    {
        mysql_close(&conn);
        return true;
    }
    else
    {
        mysql_close(&conn);
        return false;
    }
}
385
12 января 2011 года
SomewherSomehow
477 / / 25.07.2004
imAlex,
Предлагаю обсуждать клиентский софт в соотв. форуме. Тут все-таки раздел субд.
18K
12 января 2011 года
imAlex
179 / / 29.07.2010
Оки. Сори
Я пробую посчитать время:
 
Код:
UPDATE users
SET time_summ = time_out - time_in
WHERE id = 1

при этом, если в time_out секунды, минуты и часы меньше чем в time_in, то все получается, но как только хотя бы один из перечисленных больше (например 10:20:00 - 10:00:01)- результат 00:00:00 а не 00:19:59. Почему так?
8
12 января 2011 года
mfender
3.5K / / 15.06.2005
Стоп!
1. Как может time_in быть больше, чем time_out?
2. Какого типа у тебя эти поля?
385
12 января 2011 года
SomewherSomehow
477 / / 25.07.2004
Кстати, почему называется time_summ, хотя вычисляется фактически разность...
18K
12 января 2011 года
imAlex
179 / / 29.07.2010
Все три поля типа TIME. Целиком time_in не може быть больше, но зато секунды в нем запросто. В моем примере это описано:
например (time_out=10:20:00) - (time_in=10:00:01)= 00:00:00 а не 00:19:59
18K
12 января 2011 года
imAlex
179 / / 29.07.2010
Цитата: SomewherSomehow
Кстати, почему называется time_summ, хотя вычисляется фактически разность...


:) потому, что сумма времени (в данном случае сколько по времени отсутствовал)

8
12 января 2011 года
mfender
3.5K / / 15.06.2005
Цитата: imAlex
Все три поля типа TIME. Целиком time_in не може быть больше, но зато секунды в нем запросто. В моем примере это описано:
например (time_out=10:20:00) - (time_in=10:00:01)= 00:00:00 а не 00:19:59



Это потому что ты берёшь не оттуда время. Бери время сервера БД. Тогда расхождения не будет. Только в милисекундах, но с этим бороться невозможно, ибо оно разное всегда даже для уже записанных значений.

385
13 января 2011 года
SomewherSomehow
477 / / 25.07.2004
Цитата: imAlex
:) потому, что сумма времени (в данном случае сколько по времени отсутствовал)


Ну так и надо назвать time_missed, или хотя бы time_diff, дело конечно ваше, но меня подобные названия, встреть я их в чужом коде - не обрадовали бы.

8
13 января 2011 года
mfender
3.5K / / 15.06.2005
Да, блин, забыл вчера написать.
Раз у тебя MySQL, то используй тип TIMESTAMP. манипуляции с ним такие же как с TIME, но есть у него характерная особенность: ты можешь указать этому полю опцию DEFAULT CURRENT_TIMESTAMP, и вместе с INSERT туда будет записываться текущее время.
18K
13 января 2011 года
imAlex
179 / / 29.07.2010
Цитата: mfender
Это потому что ты берёшь не оттуда время. Бери время сервера БД. Тогда расхождения не будет. Только в милисекундах, но с этим бороться невозможно, ибо оно разное всегда даже для уже записанных значений.


Мы видимо не правильно друг-друга поняли. Во время выполнения программы, при старте заносится текущее время в поля time_in и time_out, далее изменяется время в поле time_out. Предположим ПК был включен в 10:30:00, а связь с инетом появилась только в 11:00:00. В таком случае с сервера время прихода я брать не могу. Тоже самое и с time_lock, time_unlock. Далее в 11:20:00 человек перестал работать (пошел поесть, покурить), вернулся в 12:00:00. Для того, чтоб вычислить сколько времени его не было на рабочем месте, необходимо выполнить сл. операцию: 12:00:00-11:20:00. Все поля имеют формат TIME. MySQL говорит, что результат такого выражения=00:00:00. Вопрос почему? как исправить? Я читал, что с полем DATETIME можно сделать сл.:

 
Код:
SELECT DATE_ADD("1998-01-01 00:00:00", INTERVAL "-1 10" DAY_HOUR);

Может есть что подобное для поля типа TIME?

Цитата: mfender
Да, блин, забыл вчера написать.
Раз у тебя MySQL, то используй тип TIMESTAMP. манипуляции с ним такие же как с TIME, но есть у него характерная особенность: ты можешь указать этому полю опцию DEFAULT CURRENT_TIMESTAMP, и вместе с INSERT туда будет записываться текущее время.


Насколько я понял, данный метод не решает мою проблему.

И еще, я вчера почти весь день убил пытаясь подключиться к базе MySQL с другого ПК (не с того, на котором стоит БД). Ничего не получилось. В Интернете вычитал целую кучу способов. Например в файле my.cnf убрать "#" перед bind-address, дальше правим config.inc.php в phpMyAdmin. И все равно не подключается. Пробовал соединение с моей проги (в поле host указывал ip или имя ПК), результат тот-же

18K
17 января 2011 года
imAlex
179 / / 29.07.2010
Всем привет.
Кто знает, как проверить соединение с базой? На данный момент я соединяюсь с ней перед каждым запросом, ну и соответственно через 110 запросов база не отвечает, т.к. превышено максимальное количество соединений ( "max_connections" ).
8
17 января 2011 года
mfender
3.5K / / 15.06.2005
А зачем подключаться перед каждым запросом? Нужно проверять, активно-ли соединение, и восстанавливать его только если оно отсутствует. Ну и разрывать когда нужно.
18K
17 января 2011 года
imAlex
179 / / 29.07.2010
Цитата: mfender
А зачем подключаться перед каждым запросом? Нужно проверять, активно-ли соединение, и восстанавливать его только если оно отсутствует. Ну и разрывать когда нужно.


Огромное спасибо за ответ.
А как проверить активно-ли соединение?

8
17 января 2011 года
mfender
3.5K / / 15.06.2005
у компоннта подключения наверняка есть булево свойство Connected. Соттветственно, if not Connected then Connect := true; (ну, это если по нашему, в Delphi). У вас с С наверняка то же, только другими словами.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог