testdb5.pp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. program testdb5;
  2. {$mode objfpc}{$H+}
  3. uses
  4. mysql57dyn;
  5. Const
  6. CHost : string = 'localhost';
  7. CDataBase : string = 'test';
  8. CQuery1 : string = 'select * from FPDEV';
  9. CQuery2 : string = 'select * from FPDEV where ID between ? and ?';
  10. var
  11. Database : string;
  12. MySQL : PMYSQL;
  13. i, real_length : integer;
  14. s : string;
  15. Res : PMYSQL_RES;
  16. Field: PMYSQL_FIELD;
  17. Row : MYSQL_ROW;
  18. Stmt : PMYSQL_STMT;
  19. BindParams : array[1..2] of MYSQL_BIND;
  20. param1: longint = 10;
  21. param2: longint = 20;
  22. BindRes : array of MYSQL_BIND;
  23. BindFields : array of record
  24. buffer: record case byte of
  25. 0: (AsLong: longint);
  26. 1: (AsLongLong: int64);
  27. 2: (AsDouble: double);
  28. 3: (AsBytes: array[0..10] of byte);
  29. end;
  30. length: dword;
  31. is_null: my_bool;
  32. error: my_bool;
  33. end;
  34. procedure MySQLError(const Msg: string);
  35. begin
  36. Writeln (stderr, Msg, ' (', mysql_errno(MySQL), ': ', mysql_error(MySQL), ')');
  37. halt(1);
  38. end;
  39. procedure MySQLStmtError(const Msg: string);
  40. begin
  41. Writeln (stderr, Msg, ' (', mysql_stmt_errno(Stmt), ': ', mysql_stmt_error(Stmt), ')');
  42. halt(1);
  43. end;
  44. begin
  45. if ParamCount=1 then
  46. Database := ParamStr(1)
  47. else
  48. Database := CDatabase;
  49. // load client library
  50. InitialiseMySQL;
  51. Write ('Connecting to ', CHost, ' MySQL...');
  52. MySQL := mysql_init(MySQL);
  53. if mysql_real_connect(MySQL, PAnsiChar(CHost), 'root', 'root', Nil, 0, Nil, CLIENT_MULTI_RESULTS) = nil then
  54. MySQLError('Couldn''t connect to MySQL.');
  55. Writeln ('Done.');
  56. Writeln ('Connection data:');
  57. writeln ('Host info : ',mysql_get_host_info(MySQL));
  58. writeln ('Server info : ',mysql_stat(MySQL));
  59. writeln ('Client info : ',mysql_get_client_info);
  60. Writeln ('Selecting Database ',DataBase,'...');
  61. if mysql_select_db(MySQL, PAnsiChar(DataBase)) <> 0 then
  62. MySQLError('Couldn''t select database '+Database);
  63. (*** Example using traditional API: ***)
  64. writeln ('Executing query : ',CQuery1,' ...');
  65. if mysql_query(MySQL, PAnsiChar(CQuery1)) <> 0 then
  66. MySQLError('Query failed');
  67. Res := mysql_store_result(MySQL);
  68. if Res=Nil then
  69. MySQLError('Query returned nil result.');
  70. Writeln ('Number of records returned : ',mysql_num_rows (Res));
  71. Writeln ('Number of fields per record : ',mysql_num_fields(Res));
  72. Row := mysql_fetch_row(Res);
  73. while (Row <> nil) do
  74. begin
  75. Write ('(');
  76. for i:=0 to mysql_num_fields(Res)-1 do
  77. begin
  78. if i > 0 then Write(', ');
  79. Field := mysql_fetch_field_direct(Res, i);
  80. Write (Field^.name, ': ', Row[0]);
  81. end;
  82. Writeln(')');
  83. Row := mysql_fetch_row(Res);
  84. end;
  85. Writeln ('Freeing memory occupied by result set...');
  86. mysql_free_result (Res);
  87. (*** Example using prepared statement API: ***)
  88. writeln ('Preparing query : ',CQuery2,' ...');
  89. Stmt := mysql_stmt_init(MySQL);
  90. if mysql_stmt_prepare(Stmt, PAnsiChar(CQuery2), length(CQuery2)) <> 0 then
  91. MySQLStmtError('Query preparation failed');
  92. Writeln ('Query has ', mysql_stmt_param_count(Stmt), ' parameters');
  93. // binding input parameters
  94. BindParams[1].buffer_type := MYSQL_TYPE_LONG;
  95. BindParams[1].buffer := @param1;
  96. BindParams[1].buffer_length := 0; // for integer type no need to specify
  97. BindParams[1].length := nil;
  98. BindParams[1].is_null := nil;
  99. BindParams[2].buffer_type := MYSQL_TYPE_LONG;
  100. BindParams[2].buffer := @param2;
  101. if mysql_stmt_bind_param(Stmt, @BindParams[1]) <> 0 then
  102. MySQLStmtError('Parameters binding failed');
  103. writeln ('Executing query : ',CQuery2,' ...');
  104. if mysql_stmt_execute(Stmt) <> 0 then
  105. MySQLStmtError('Query execution failed');
  106. //mysql_stmt_store_result(Stmt); // optional; but may be required when using later "mysql_stmt_num_rows()"
  107. Writeln ('Number of records returned : ',mysql_stmt_num_rows (Stmt));
  108. Writeln ('Number of fields per record : ',mysql_stmt_field_count(Stmt));
  109. // prepare structures for output field binding
  110. SetLength(BindRes , mysql_stmt_field_count(Stmt));
  111. SetLength(BindFields, mysql_stmt_field_count(Stmt));
  112. Res := mysql_stmt_result_metadata(Stmt); // Fetch result set meta information
  113. Field := mysql_fetch_fields(Res);
  114. // for each field in result set prepare result buffer
  115. for i:=0 to mysql_stmt_field_count(Stmt)-1 do
  116. begin
  117. BindRes[i].buffer_type := Field^.ftype;
  118. BindRes[i].buffer_length := 9;
  119. BindRes[i].buffer := @BindFields[i].buffer;
  120. BindRes[i].length := @BindFields[i].length;
  121. BindRes[i].is_null := @BindFields[i].is_null;
  122. BindRes[i].error := @BindFields[i].error;
  123. Inc(Field);
  124. end;
  125. if mysql_stmt_bind_result(Stmt, @BindRes[0]) <> 0 then
  126. MySQLStmtError('Bind result failed');
  127. // if output buffer is smaller than length of character data MYSQL_DATA_TRUNCATED is returned
  128. // and "error" member of MYSQL_BIND structure is set
  129. while mysql_stmt_fetch(Stmt) in [0, MYSQL_DATA_TRUNCATED] do
  130. begin
  131. for i:=0 to mysql_stmt_field_count(Stmt)-1 do
  132. begin
  133. if i > 0 then Write(', ');
  134. // check real length and set up space in result buffer
  135. real_length := BindFields[i].length;
  136. if BindRes[i].buffer_type in [MYSQL_TYPE_STRING, MYSQL_TYPE_VAR_STRING] then
  137. if real_length > 9 then
  138. begin
  139. // prepare buffer with required length
  140. SetLength(s, real_length);
  141. BindRes[i].buffer := @s[1];
  142. BindRes[i].buffer_length := real_length;
  143. // fetch again
  144. mysql_stmt_fetch_column(Stmt, @BindRes[i], i, 0);
  145. Write(s);
  146. end
  147. else
  148. begin
  149. SetString(s, BindRes[i].buffer, real_length);
  150. Write(s);
  151. end
  152. else
  153. Write(BindFields[i].buffer.AsLong);
  154. end;
  155. Writeln;
  156. end;
  157. mysql_free_result(Res); // Free the prepared result metadata
  158. mysql_stmt_free_result(Stmt);
  159. mysql_stmt_close(Stmt);
  160. Writeln ('Closing connection with MySQL.');
  161. mysql_close(MySQL);
  162. // unload client library
  163. ReleaseMySQL;
  164. halt(0);
  165. end.