Linux数据库大比拚[5]

[入库:2005年9月19日] [更新:2007年3月25日]

本文简介:

  WHOLESALE_PRICE MONEY,
  RETAIL_PRICE MONEY,
  COPIES_AVAILABLE INTEGER
  )
  DROP TABLE CUSTOMER
  CREATE TABLE CUSTOMER (
  CUSTOMER_NO INTEGER NOT NULL,
  FIRST_NAMES CHARACTER(30),
  LAST_NAMES CHARACTER(30),
  STREET CHARACTER(30),
  HOUSE_NO SMALLINT,
  POSTCODE CHARACTER(7),
  TOWN CHARACTER(30),
  ISO_COUNTRY_CODE CHARACTER(2)
  )
  DROP TABLE BOOKORDER
  CREATE TABLE BOOKORDER (
  ORDER_NO INTEGER NOT NULL,
  CUSTOMER_NO INTEGER NOT NULL,
  ORDERED DATE,
  DELIVERY DATE,
  STATUS CHARACTER(1)
  )
  DROP TABLE ORDER_POSITION
  CREATE TABLE ORDER_POSITION (
  POSITION_NO INTEGER NOT NULL,
  ORDER_NO INTEGER NOT NULL,
  ARTICLE_NO INTEGER NOT NULL,
  NUMBER SMALLINT
  )
  DROP TABLE RATING
  CREATE TABLE RATING (
  RATING_NO INTEGER NOT NULL,
  ARTICLE_NO INTEGER NOT NULL,
  SCORE SMALLINT,
  COMMENT TEXT(255)
  )
  
    几乎所有的约束都不见了,并且NUMERIC和CHARACTER VARYING分别由MONEY和TEXT代替。
  
    在mSQL的监视程序中有令人沮丧的不足:它似乎不能接受从标准输入输入SQL脚本,这样, 需要剪切/粘贴代码。mSQL也讨厌分号;最终我只能一个一个地输入命令并用\g(“go”斜杠命令)终止每条命令 。
  
    实现测试客户
  
    为了比较3个数据库管理器,我决定为执行在bookstore数据库上的交易的目的用C写了一个测试客户。结果,我实现了一些操作,它们能比较API。为了性能比较,我随后充分实现了它们,并且把一个非交互式模式加入客户程序,因此它能自己运行,产生随意的数据且随机执行交易。
  
    我决定了在样品数据库上实现下列行动:
  
    增加一本新书: INSERT INTO BOOK (...) VALUES (...);
    删除一本存在的书: DELETE FROM BOOK WHERE ARTICLE_NO=...;
    增加一个顾客: INSERT INTO CUSTOMER (...) VALUES (...);
    删除一个顾客: DELETE FROM CUSTOMER WHERE CUSTOMER_NO=...;
    订书的一个顾客: INSERT INTO BOOKORDER (...) VALUES (...); INSERT INTO ORDER_POSITION (...) VALUES (...);;
    评估一本书的一个顾客: INSERT INTO RATING (...) VALUES (...);
    改变一份订单的状态: UPDATE BOOKORDER SET STATUS=... WHERE ORDER_NO=...;
  
    然后,能生成下列报表:
  
    书籍列表: SELECT * FROM BOOK;
    顾客列表: SELECT * FROM CUSTOMER;
    正在投递的交货表,按状态排序: SELECT * FROM BOOKORDER ORDER BY STATUS;
    书籍的利润额,最后有平均值: SELECT RETAIL_PRICE-WHOLESALE_PRICE FROM BOOK; SELECT AVG(RETAIL_PRICE-WHOLESALE_PRICE) FROM BOOK;
    书评、评级和为一本书的平均评级: SELECT * FROM RATING WHERE ARTICLE_NO=...; SELECT AVG(SCORE) FROM RATING WHERE ARTICLE_NO=...;
  
    将客户带入PostgreSQL的生活
  
    关于用C编程PostgreSQL的好处是你能使用嵌入式SQL。(而且,至少我喜欢它)它不是很好地文档化,但是ESQL预处理器ecpg运行并能产生PostgreSQL接口代码就好。Sql 的定式思维方法有时妨碍了我;但是,开发客户程序并不是很难的。
  
    我说过“不是很好地文档化”吗?那是一个保守说法。否则PostgreSQL完整的HTML 文档在这方面非常缺乏。我从书本得到的ESQL知识是初级的,而且联机文档没帮助太多,因此我不得不自己了解如何由ecpg将C的变量强制转换为NUMERIC值--还有其他东西,而且,ESQL预处理器不是很详细,且无论何时它碰到任何小错误,总是似乎完全释放出来,这对任何从事又长期准备的项目的人来说将是一个持久战。
  
    在编程PostgreSQL的客户程序时,我碰到了一些小错误。例如,如果文档记录是可能的话,在声明一个光标(cursor)时,ecpg将不接受一个 FOR READ ONLY子句 。ORDER BY子句甚至没被实现。我遇见的问题大都ecpg预处理器有关。Postgres有一个 C API(不管怎么说,ESQL需要被编译进一些东西),它可能是优秀的,但是我没使用它(这就是生活)。当有ESQL时,我准备使用ESQL。
  
    这是摘自postgres-client.pgc的list_books()函数:
  
  void list_books(void)
  {
  EXEC SQL BEGIN DECLARE SECTION;
  int article_no;
  char author_first_names[30];
  char author_last_names[30];
  char title[30];
  char isbn[14];
  int wholesale_price;
  int retail_price;
  int copies_available;
  EXEC SQL END DECLARE SECTION;
  EXEC SQL DECLARE book_cursor CURSOR FOR
  SELECT ARTICLE_NO, AUTHOR_FIRST_NAMES, AUTHOR_LAST_NAMES,
  TITLE, ISBN, WHOLESALE_PRICE, RETAIL_PRICE,
  COPIES_AVAILABLE FROM BOOK;
  EXEC SQL OPEN book_cursor;
  while (1)
  {
  EXEC SQL FETCH NEXT FROM book_cursor
  INTO :article_no, :author_first_names, :author_last_names,
  :title, :isbn, :wholesale_price, :retail_price,
  :copies_available;
  if (sqlca.sqlcode == 100) /* 100 == NOT FOUND */
  break; /* bail out */
  printf("\nArticle no. %d\n", article_no);
  printf("%s, %s:\n", author_last_names, author_first_names);
  printf(" %s (%s)\n", title, isbn);
  printf("Bought at %d; selling at %d; %d copies available\n\n",

本文关键:Linux数据库大比拚
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top