MySQL C Интерфейс (край) - Програмиране от

Основни въпроси и проблеми при използването на C интерфейса



Защо mysql_store_result () понякога връща NULL след успешни връщания на mysql_query ()?

Функцията mysql_store_result () може да върне NULL след успешно извикване на mysql_query (). Това може да означава следното:


Функцията mallow () не бе успешна (например, ако полученият набор от данни е твърде голям).


Винаги можете да проверите дали дадена команда е върнала непразен резултат, като извикате функцията mysql_field_count (). Ако mysql_field_count () връща нула, тогава този набор от резултати е празен и последната заявка е команда, която не връща стойност на резултата (например INSERT или DELETE). Ако функцията mysql_field_count () връща стойност, различна от нула, тогава тази команда трябва да е върнала непразен резултат (вижте описанието на функцията mysql_field_count ()).


Можете да тествате описаните ситуации за грешки, като извикате функциите mysql_error () или mysql_errno (). .


Какви резултати могат да бъдат получени от заявка?

В допълнение към получения набор от данни, върнат от заявката, можете да получите и следната информация:


Mysql_affected_rows () връща броя на редовете, засегнати по време на последната заявка в INSERT, UPDATE или DELETE. Изключение е когато използвате DELETE без клауза WHERE, когато таблицата се пресъздава като празна, което е много по-бързо! В този случай mysql_affected_rows () връща нула като броя на засегнатите записи.

Функцията Mysql_num_rows () връща броя на редовете в получения набор от данни. Mysql_num_rows () може да бъде извикан веднага след връщането на mysql_store_result (). Заедно с функцията mysql_use_result (), функцията mysql_num_rows () може да бъде извикана само след като всички редове са извлечени с помощта на функцията mysql_fetch_row (). .

Mysql_insert_id () връща идентификатора, генериран от последната заявка, допринесла за ред в таблица с автоматично увеличаващо се поле (AUTO_INCREMENT, mysql_insert_id ()).

Някои заявки (LOAD DATA INFILE., INSERT INTO. SELECT., UPDATE) връщат допълнителна информация. Може да се получи с помощта на функцията mysql_info (). За описание на формата на върнатия низ вижте описанието на функцията mysql_info (). Ако няма допълнителна информация, тогава функцията mysql_info () връща NULL указател .


Как да получите уникалния идентификатор за последния вмъкнат ред?


Когато правите запис в таблица, съдържаща колона с атрибут AUTO_INCREMENT, последният генериран идентификатор може да бъде получен чрез извикване на mysql_insert_id () .


Можете също да използвате функцията LAST_INSERT_ID () в низа на заявката, предаден на mysql_query (), за да извлечете този идентификатор. .


Можете да изпълните следния код, за да проверите дали полето AUTO_INCREMENT се използва или не. Този код също така проверява дали дадената заявка е INSERT с помощта на AUTO_INCREMENT:


Най-скоро генерираната стойност на идентификатора се съхранява на сървъра за целия живот на тази връзка. Тази стойност не може да бъде променена от друг клиент, освен това няма да бъде променена, дори ако друга колона AUTO_INCREMENT се актуализира с определена стойност (т.е. не е NULL или 0).


И идентификаторът, генериран за една таблица, може да бъде вмъкнат в друга таблица с помощта на SQL команди, както е показано по-долу:


Свързване на проблеми с C интерфейса


Когато свързвате програма с клиентска библиотека C, на някои системи могат да възникнат следните проблеми:


Ако това се случи във вашата система, тогава трябва да свържете математическата библиотека, като добавите параметъра -lm в края на реда за компилация/свързване.


Изграждане на клиентски програми


Клиентите на MySQL, създадени от вас или получени от трети страни, трябва да бъдат свързани, когато се компилират с помощта на опциите -lmysqlclient -lz към командата link. Може да се наложи да посочите опцията -L, за да кажете на линкера местоположението на тази библиотека. Например, ако библиотеката е инсталирана в директорията '/ usr/local/mysql/lib', трябва да използвате израза -L/usr/local/mysql/lib -lmysqlclient -lz в командата за връзка .


За клиенти, използващи MySQL заглавни файлове, може да се наложи опцията -I (например -I/usr/local/mysql/include) по време на компилацията, за да може компилаторът да намери необходимите заглавни файлове.


Как да създам клиентска програма с потоци


Клиентската библиотека е почти безопасна, когато се използва в многонишков режим. Най-големият проблем е, че функциите в 'net.c', които четат от сокети, не поддържат прекъсвания. Те са проектирани с предположението, че потребителят може да иска собствена аларма, която може да прекъсва твърде дълго четене от сървъра. Когато инсталирате манипулатори на прекъсвания за прекъсване SIGPIPE, управлението на сокета трябва да бъде безопасно за нишки.


В по-ранните двоични файлове на MySQL, които ние (разработчиците на MySQL) разпространихме от нашия уебсайт (http://www.mysql.com/), клиентските библиотеки обикновено не бяха компилирани с поддръжка на нишки (двоичните файлове на Windows се компилират по подразбиране като поддържащи потоци) . По-новите двоични файлове трябва да имат както нормална, така и безопасна клиентска библиотека.


За да получите клиентска програма, обезопасена от нишки, с възможност за прекъсване от други нишки и задаване на заключване на времето при свързване към MySQL сървъра, трябва да използвате библиотеките -lmysys, -lmystrings и -ldbug библиотеки, както и 'net_serv .o 'код, използван от този сървър.


Ако не се нуждаете от прекъсвания или временни заключвания, можете просто да компилирате клиентската библиотека, безопасна за нишки (mysqlclient_r) и да я използвате (вижте MySQL C Interface). В този случай няма нужда да се притеснявате за обектния файл net_serv.o или други библиотеки на MySQL.


Ако трябва да използвате временни заключвания и прекъсвания, когато използвате клиент с резби, можете успешно да използвате подпрограмите от файла 'thr_alarm.c'. Когато използвате рутини от библиотеката на mysys, не забравяйте първо да се обадите на my_init ()! Вижте раздел Описания на C функции, свързани с потоци.


Всички функции с изключение на mysql_real_connect () по подразбиране са безопасни за нишки. По-долу са указания как да компилирате клиентска библиотека, защитена от нишки, и да я използвате в този режим (бележките за mysql_real_connect () са верни и за mysql_connect (), но тъй като mysql_connect () все пак трябва да използвате mysql_real_connect () ).


За да направите функцията mysql_real_connect () безопасна за нишките, трябва да прекомпилирате клиентската библиотека със следната команда:

Това ще създаде клиентска библиотека за нишки libmysqlclient_r (ако приемем, че операционната система включва функцията gethostbyname_r () с резба). Тази библиотека поддържа поточна поддръжка за тази връзка. Възможно е да позволите на два потока да използват една и съща връзка със следните предупреждения:


Две нишки не могат да изпращат заявка до MySQL сървъра едновременно на една и съща връзка. По-специално, трябва да сте сигурни,
че в интервалите между извикванията на функциите mysql_query () и mysql_store_result (), никоя друга нишка не използва същото
съединение.

Много нишки имат достъп до различни набори от данни с резултати, извлечени от mysql_store_result () .

Когато използвате функцията mysql_use_result, трябва да се уверите, че никоя друга нишка не използва същата връзка, докато даденият набор от резултати не бъде обработен. Въпреки това, наистина най-добрият вариант за стрийминг на клиенти, споделящи същото
и същата връзка е да приложите функцията mysql_store_result () .

Ако трябва да използвате голям брой нишки на една и съща връзка, тогава трябва да имате заключване за синхронизация срещу извикване на комбинация от функциите mysql_query () и mysql_store_result (). Веднага след като изпълнението на функцията mysql_store_result () приключи, това заключване може да бъде освободено и други нишки могат да поискат същата връзка.

Ако програмирате с POSIX нишки, можете да използвате функциите pthread_mutex_lock () и pthread_mutex_unlock (), за да зададете и освободите заключване за синхронизиране.


Трябва да знаете следното: ако има нишка, извикана от функцията MySQL, която не е създала тази връзка с базата данни MySQL, тогава:
Когато извикате mysql_init () или mysql_connect (), MySQL ще създаде специални променливи за тази нишка, които (наред с други приложения) се използват от библиотеката за отстраняване на грешки.


Ако функцията MySQL бъде извикана преди нишката да извика функциите mysql_init () или mysql_connect (), тази нишка в този случай няма да има необходимите специални променливи на нишки и вероятно програмата рано или късно ще умре с дъмп на основната памет.

За по-плавна работа на програмата направете следното:


Извикайте функцията my_init (), когато тази програма стартира, ако извика друга функция на MySQL, преди да извика функцията
mysql_real_connect () .

Извикайте функцията mysql_thread_init () в манипулатора на нишки, преди да извикате друга MySQL функция.

В тази нишка извикайте функцията mysql_thread_end (), преди да извикате pthread_exit (). Това ще освободи паметта, заета от специфични за MySQL променливи на нишки.


Имайте предвид, че може да получите някои грешки поради недефинирани символи, когато свързвате клиента с библиотеката libmysqlclient_r. В повечето случаи това се дължи на факта, че библиотеките на потока не са включени в реда за свързване/компилиране.