跳轉到內容

GLPK/Table 語句

來自華夏公益教科書,開放的書籍,開放的世界

Table 語句可用於將資料從外部資料來源讀入模型物件,包括集合和引數。Table 語句還可用於將模型結果寫回外部資料來源。當前為ODBC資料庫,尤其是MySQL資料庫,CSV檔案,以及dBase檔案提供驅動程式。

官方文件

[編輯 | 編輯原始碼]

GLPK 官方文件檔案doc/gmpl.pdf(在 GLPK 4.45 之前doc/tables.pdf) 包含 GMPL 表功能的完整參考。請參閱獲取 GLPK。此頁面僅提供指標和示例。

從 4.45 版開始,以下資訊丟失了
欄位名由字母 [A-Z,a-z] 和數字 [0-9] 字元組成,區分大小寫。它不需要是唯一的[1]

逗號分隔值 (CSV) 檔案的格式在RFC 4180[1]中描述。

對於 CSV 檔案,驅動程式識別符號為“CSV”。table OUT 語句將完全替換任何現有檔案。

CSV 表驅動程式具有以下內建限制

  • 列數必須小於或等於 50。
  • 每個值的長度必須小於或等於 100 個字元。

以下示例展示了 CSV 檔案的讀取和寫入

# test1.mod writes CSV file
set I := {1..300};
set J := {1..20};
set K := {1..100};
param  x{I,J,K} := Uniform01();
table tout {i in I, j in J, k in K} OUT "CSV" "test.csv" :
i, j, k, x[i,j,k];
end;
# test2.mod reads CSV file
set I, dimen 3;
param  x{I};
table tin IN "CSV" "test.csv" :
I <- [i,j,k], x;
printf "Number of values: %d\n", card(I);
printf "Average value: %f\n", (sum{(i,j,k) in I} x[i,j,k]) / card(I);
end;

對於dBase檔案,驅動程式識別符號為“xBASE”。table OUT 語句將完全替換任何現有檔案。

dBase 表驅動程式具有以下內建限制

  • 列數必須小於或等於 50。
  • 每個值的長度必須小於或等於 100 個字元。

對於ODBC資料庫連線,驅動程式識別符號為“ODBC”。對於本機MySQL資料庫連線,驅動程式識別符號為“MySQL”。

請注意,table UPDATE 和 table INSERT 語句必須後跟 table OUT 語句才能生效(如執行 SQL部分所述)。

使用 MySQL 表驅動程式時,table 語句可以充分利用連線的資料庫提供的SQL命令。MySQL REPLACE 語句是 SQL 的非標準擴充套件,它意味著隨後的 table OUT 語句。

table IN 語句與其他 SQL 語句結合使用,可用於從關係資料庫中選擇資料。例如

set I, dimen 2;
param st{I};
table t IN
  'ODBC' 'FILEDSN=supply.dsn'
  'SELECT product, period, quantity'
  '  FROM stock' :
  I <- [product, period], st ~ quantity;

不用 SELECT 語句,可以提供表名。在這種情況下,將選擇整個表。

set I, dimen 2;
param st{I};
table t IN
  'ODBC' 'FILEDSN=supply.dsn'
  'stock' :
  I <- [product, period], st ~ quantity;

SELECT 語句(或表名)可以由其他 SQL 語句作為字首

set I, dimen 2;
param st{I};
table t IN
  'ODBC' 'FILEDSN=supply.dsn'
  'DROP TABLE IF EXISTS result;'
  'CREATE TABLE result ('
  '  product  TEXT(40),'
  '  period   INTEGER,'
  '  quantity FLOAT,'
  '  PRIMARY KEY ( product(40), period ) );'
  'SELECT product, period, quantity'
  '  FROM stock' :
  I <- [product, period], st ~ quantity;

可以將 SQL 語句拆分為多個字串以克服 GLPK 中100 個字元單行字串長度限制。在這種情況下,SQL 語句的終止由在多行呼叫(如上所示)的最後一個字元中存在未加引號的分號來指示。

從 GLPK 4.44 開始,GLPK 使用 ODBC 和 MySQL 驅動程式時,會自動從字串中修剪尾隨空格 (0x20) 字元。strtrim()函式。

table OUT

[編輯 | 編輯原始碼]

table OUT 語句與其他 SQL 語句結合使用,可用於在關係資料庫中插入、更新或刪除記錄。

INSERT 語句可用於將記錄插入關係資料庫。例如

table t {p in P, t in T} OUT
  'ODBC' 'FILEDSN=supply.dsn'
  'INSERT INTO stock'
  '  ( product, period, quantity) '
  '  VALUES (?,?,?)' :
  p, t, st[p, t];

如果最後一個 SQL 語句不包含作為值佔位符的問號,則需要表名。該表名和提供的列名將用於構建 INSERT 語句。

table t {p in P, t in T} OUT
  'ODBC' 'FILEDSN=supply.dsn'
  'stock':
  p ~ product, t ~ period, st[p, t] ~ quantity;

迭代的最終 SQL 語句可以由其他 SQL 語句作為字首

table t {p in P, t in T} OUT
  'ODBC' 'FILEDSN=supply.dsn'
  'DELETE FROM stock;'
  'INSERT INTO stock'
  '  ( product, period, quantity) '
  '  VALUES (?,?,?)' :
  p, t, st[p, t];

這種策略可以用於避免重複插入。

可以發出 INSERT 以外的語句。例如,UPDATE 語句可用於更新關係資料庫中的記錄。例如

table t {p in P, t in T} OUT
  'ODBC' 'FILEDSN=supply.dsn'
  'UPDATE stock'
  '  SET quantity = ?'
  '  WHERE'
  '    product = ? AND period = ?;' :
  st[p, t], p, t;

DELETE 語句可用於從關係資料庫中刪除記錄。例如

table t {p in P, t in T} OUT
  'ODBC' 'FILEDSN=supply.dsn'
  'DELETE FROM stock'
  '  WHERE'
  '    product = ? AND period = ?;' :
  p, t;

執行 SQL

[編輯 | 編輯原始碼]

目前,GMPL 語言中的 SQL 支援僅允許在“table IN”和“table OUT”語句塊中發出 SQL 命令。

在“table IN”塊中,最終的 SELECT 語句(或表名)可以由任意數量的準備 SQL 語句作為字首。

在“table OUT”塊中,迭代域的最終 INSERT/DELETE/UPDATE 語句可以由任意數量的準備 SQL 語句作為字首。

為了將準備語句與資料庫 I/O 完全分開,可以使用虛擬輸出語句

table prep {i in 1..1} OUT 'ODBC'
  'DSN=glpk;UID=glpk;PWD=gnu'
  # The preparatory SQL statement(s) follow
  'DELETE FROM stock;'
  # The next SQL statement is needed to satisfy the GMPL syntax.
  'SELECT ?;' : i; 

Table 語句錯誤(已在 GLPK 4.45 中修復)

[編輯 | 編輯原始碼]

在 4.45 版之前的 GLPK 版本中,處理 table 語句時可能會遇到記憶體溢位錯誤。該問題在此主題中進行了描述,現在已解決。

參考文獻

[編輯 | 編輯原始碼]
  1. Y. Shafranovich (October 2005). "Common Format and MIME Type for Comma-Separated Values (CSV) Files".
華夏公益教科書