1. 程式人生 > 資料庫 >MySQL的SQL語句 - 資料操作語句(12)- SELECT 語句(2)

MySQL的SQL語句 - 資料操作語句(12)- SELECT 語句(2)

SELECT ... INTO 語句

SELECT 的 SELECT ... INTO 形式將查詢結果儲存在變數中或寫入檔案:

SELECT ... INTO var_list 選擇列值並將它們儲存到變數中。

SELECT ... INTO OUTFILE 將所選行寫入檔案。可以指定列和行終止符以生成特定的輸出格式。

SELECT ... INTO DUMPFILE 在沒有任何格式的情況下將單行寫入檔案。

給定的 SELECT 語句最多可以包含一個 INTO 子句,但如 SELECT 語法描述所示,INTO 可以出現在不同的位置:

● 在 FROM 之前。例如:

1. SELECT * INTO @myvar FROM t1;

● 在後面的鎖定子句之前。例子:

1. SELECT * FROM t1 INTO @myvar FOR UPDATE;

● 在 SELECT 語句的最後。例如:

1. SELECT * FROM t1 FOR UPDATE INTO @myvar;

從 MySQL 8.0.20 開始支援在語句末尾使用 INTO,並且是首選位置。從 MySQL 8.0.20 開始,不推薦使用鎖定子句之前使用 INTO,並且在將來的 MySQL 版本中將刪除對它的支援。換句話說,INTO 用於 FROM 之後而不是在 SELECT 語句的末尾將生成一個警告。

INTO 子句不應在巢狀的 SELECT 中使用,因為這樣的 SELECT 必須將其結果返回到外部上下文。在 UNION 語句中使用 INTO 也有一些限制。

對於INTO var_list 變數:

● var_list 列出一個或多個變數的列表,每個變數可以是使用者定義的變數、儲存過程或函式引數,或儲存程式區域性變數。(在預編譯 SELECT ... INTO var_list 語句中,只允許使用使用者定義的變數。)

● 選定的值將分配給變數。變數數必須與列數匹配。查詢應該返回一行。如果查詢沒有返回任何行,則會出現錯誤程式碼1329的警告(沒有資料),變數值保持不變。如果查詢返回多行,則出現錯誤1172(結果由多行組成)。如果語句可能檢索到多行,則可以使用 LIMIT 1 將結果集限制為一行。

1. SELECT id, data INTO @x, @y FROM test.t1 LIMIT 1;

INTO var_list 也可以與 TABLE 語句一起使用,但受以下約束限制:

● 變數數必須與表中的列數匹配。

● 如果表包含多行,則必須使用 LIMIT 1 將結果集限制為單行。LIMIT 1 必須在 INTO 關鍵字之前。

下面是這樣一個語句的示例:

1. TABLE employees ORDER BY lname DESC LIMIT 1
2.     INTO @id, @fname, @lname, @hired, @separated, @job_code, @store_id;

VALUES 語句生成的單行記錄儲存到一組使用者變數中,也可以從這些變數中選擇值。在這種情況下,必須使用表別名,必須將值列表中的每個值分配給變數。這裡顯示的兩個語句都相當於 SET @x=2, @y=4, @z=8:

1. SELECT * FROM (VALUES ROW(2,4,8)) AS t INTO @x,@y,@z;
2. 
3. SELECT * FROM (VALUES ROW(2,4,8)) AS t(a,b,c) INTO @x,@y,@z;

使用者變數名不區分大小寫。

SELECT 語句的 SELECT ... INTO OUTFILE 'file_name' 形式將所選行寫入檔案。檔案是在伺服器主機上建立的,因此必須具有 FILE 許可權才能使用此語法。file_name 不能是現有的檔案,這樣可以防止修改 /etc/passwd 和資料庫表等檔案。character_set_filesystem 系統變數控制檔名的解釋。

SELECT ... INTO OUTFILE 語句用於將錶轉儲到伺服器主機上的文字檔案。要在其他主機上建立結果檔案,SELECT ... INTO OUTFILE 通常不適合,因為無法相對於伺服器主機檔案系統的檔案路徑寫入檔案,除非可以使用伺服器主機檔案系統上的網路對映路徑訪問遠端主機上的檔案位置。

或者,如果 MySQL 客戶端軟體安裝在遠端主機上,則可以使用客戶端命令例如 mysql -e "SELECT ..." > file_name 在該主機上生成檔案。

SELECT ... INTO OUTFILE 語句是對 LOAD DATA 的補充。列值被寫入檔案並轉換為 CHARACTER SET 子句中指定的字符集。如果不存在這樣的子句,則使用二進位制字符集轉儲值。實際上,沒有字符集轉換。如果結果集包含多個字符集的列,則輸出資料檔案也將包含這些列,並且可能無法正確重新載入該檔案。

語句的 export_options 部分的語法同樣也包含與 LOAD DATA 語句一起使用的 FIELDS 和 LINES 子句。

FIELDS ESCAPED BY 控制如何寫入特殊字元。如果 FIELDS ESCAPED BY 字元不為空,則在必要時輸出以下字元時作為字首,以避免歧義:

● FIELDS ESCAPED BY 字元

● FIELDS [OPTIONALLY] ENCLOSED BY 字元

● FIELDS TERMINATED BY 和 LINES TERMINATED BY 值的第一個字元

● ASCII NUL(零值位元組;轉義符後面實際寫入的是ASCII 0,而不是零值位元組)

FIELDS TERMINATED BY、ENCLOSED BY、ESCAPED BY 或 LINES TERMINATED BY 必須轉義,這樣才能可靠地讀迴文件。對 ASCII NUL 進行轉義,以使某些分頁命令更易於檢視。

生成的檔案不需要符合 SQL 語法,因此不需要轉義其他什麼。

如果 FIELDS ESCAPED BY 字元為空,則不轉義任何字元,並且 NULL 輸出仍然為 NULL,而不是 \N。指定空轉義字元可能不是一個好主意,尤其是當資料中的欄位值包含剛剛給出的列表中的任何字元時。

當要將表的所有列轉儲到文字檔案中時,INTO OUTFILE 也可以與 TABLE 語句一起使用。在這種情況下,可以使用 ORDER BY 和 LIMIT 控制行的順序和數量;這些子句必須在 INTO OUTFILE 之前。TABLE ... INTO OUTFILE 支援與 SELECT ... INTO OUTFILE 相同的 export_options 選項,它在寫入檔案系統時受到相同的限制。下面是這樣一個語句的示例:


1. TABLE employees ORDER BY lname LIMIT 1000
2.     INTO OUTFILE '/tmp/employee_data_1.txt'
3.     FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"', ESCAPED BY '\'
4.     LINES TERMINATED BY '\n';

還可以使用 SELECT ... INTO OUTFILE 和 VALUES 語句將值直接寫入檔案。示例如下:

1. SELECT * FROM (VALUES ROW(1,2,3),ROW(4,5,6),ROW(7,8,9)) AS t
2.     INTO OUTFILE '/tmp/select-values.txt';

必須使用表別名;也支援列別名,並且可以選擇僅寫入所需列值。還可以使用 SELECT ... INTO OUTFILE 支援的任何輸出選項來格式化輸出到檔案的內容。

下面是一個示例,該示例以逗號分隔值(CSV)格式生成檔案,該格式由許多程式使用:

1. SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
2.   FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
3.   LINES TERMINATED BY '\n'
4.   FROM test_table;

如果使用 INTO DUMPFILE 而不是 INTO OUTFILE,MySQL 只向檔案中寫入一行,沒有任何列或行終止,也不執行任何轉義處理。這對於查詢 BLOB 值並將其儲存在檔案中非常有用。

TABLE 還支援 INTO DUMPFILE。如果表包含多行,則還必須使用 LIMIT 1 將輸出限制為單行。INTO DUMPFILE 也可以與 SELECT * FROM (VALUES ROW()[, ...]) AS table_alias [LIMIT 1] 語句一起使用。

注意

INTO OUTFILE 或 INTO DUMPFILE 建立的任何檔案都屬於 mysqld 執行帳戶下的作業系統使用者。(由於這個和其他原因,不應該以 root 使用者身份執行 mysqld。)從 MySQL 8.0.17 開始,用於檔案建立的 umask 是 0640;必須有足夠的訪問許可權來操作檔案內容。在 MySQL 8.0.17 之前,umask 是 0666,伺服器主機上的所有使用者都可以寫入該檔案。

如果 secure_file_priv 系統變數設定為非空目錄名,則要寫入的檔案必須位於該目錄中。

在事件排程器執行的事件中,作為其中一部分的 SELECT ... INTO 語句上下文中,診斷訊息(不僅包括錯誤,還包括警告)將寫入錯誤日誌,在 Windows 上寫入應用程式事件日誌。

從 MySQL 8.0.22 開始,通過設定 select_into_disk_sync 伺服器系統變數,支援定期同步由 SELECT INTO OUTFILE 和 SELECT INTO DUMPFILE 寫入的輸出檔案。通過設定 select_into_buffer_size 和 select_into_disk_sync_delay,可以設定輸出緩衝區大小和延遲。

官方網站: