mysql存儲過程建表
二個關鍵:
第一,你的訪問用戶,是否對此
二表
有相同的許可權,若是,剛一切皆很簡單。
第二,你在描述其中的某個表時,只需加一個資料庫名即可。即select
wc.table.name
from
wc.table,wcw.table2.name
2. 為什麼在mysql存儲過程中創建的臨時表不能
提到MySQL臨時表,我們都很熟悉了,一般來說,分為兩類:
1. MySQL 臨時表引擎,名字叫做 Memory。比如
create table tmp1(id int, str1 varchar(100) ) engine = memory;
由參數max_heap_table_size 來控制,超過報錯。
2. 非臨時表的引擎,這里又分為兩類:
用戶自定義的臨時表,比如:
- create temporary table (id int, str1 varchar(100) );
SQL執行過程中產生的內部臨時表,比如:UNION , 聚合類ORDER BY,派生表,大對象欄位的查詢,子查詢或者半連接的固化等等場景。
- mysql> show status like '%tmp_%tables%';``+-------------------------+-------+``| Variable_name | Value |``+-------------------------+-------+``| Created_tmp_disk_tables | 0 |``| Created_tmp_tables | 0 |``+-------------------------+-------+``2 rows in set (0.00 sec)
VARCHAR的變長存儲。那就是如果臨時表的欄位定義是 VARCHAR(200),那麼映射到內存里處理的欄位變為CHAR(200)。假設 VARCHAR(200) 就存里一個字元 "Y", 那豈不是很大的浪費。
大對象的默認磁碟存儲,比如 TEXT,BLOB, JSON等,不管裡面存放了啥,直接轉化為磁碟存儲。
- mysql> SELECT * FROM performance_schema. memory_summary_global_by_event_name WHERE event_name like '%temptable%'G*************************** 1. row *************************** EVENT_NAME: **memory/temptable/physical_disk** COUNT_ALLOC: 0 COUNT_FREE: 0 SUM_NUMBER_OF_BYTES_ALLOC: 0 SUM_NUMBER_OF_BYTES_FREE: 0 LOW_COUNT_USED: 0 CURRENT_COUNT_USED: 0 HIGH_COUNT_USED: 0 LOW_NUMBER_OF_BYTES_USED: 0CURRENT_NUMBER_OF_BYTES_USED: 0 HIGH_NUMBER_OF_BYTES_USED: 0*************************** 2. row *************************** EVENT_NAME: **memory/temptable/physical_ram** COUNT_ALLOC: 1 COUNT_FREE: 0 SUM_NUMBER_OF_BYTES_ALLOC: 1048576 SUM_NUMBER_OF_BYTES_FREE: 0 LOW_COUNT_USED: 0 CURRENT_COUNT_USED: 1 HIGH_COUNT_USED: 1 LOW_NUMBER_OF_BYTES_USED: 0CURRENT_NUMBER_OF_BYTES_USED: 1048576 HIGH_NUMBER_OF_BYTES_USED: 10485762 rows in set (0.03 sec)
默認內部臨時表引擎。
支持變長字元類型的實際存儲。
設置變數 temp_table_max_ram 來控制實際存儲內存區域大小。
那麼這兩種臨時表的計數器通常用show global status like '%tmp_%tables%' 來查看。比如
以上結果分別代表,只創建磁碟上的臨時表計數以及臨時表的總計數。這兩個計數器由參數 tmp_table_size 和 max_heap_table_size 兩個取最小值來控制。
那在 MySQL 5.7 之前,這個 SQL 運行中產生的臨時表是 MYISAM,而且只能是 MYISAM。那 MySQL 從 5.7 開始提供了參數 Internal_tmp_mem_storage_engine 來定義內部的臨時表引擎,可選值為 MYISAM 和 INNODB 。當然這里我們選擇 INNODB 。並且把內部的臨時表默認保存在臨時表空間 ibtmp1 (可以用參數 innodb_temp_data_file_path 設置大小以及步長等)下。當然這里我們得控制下 ibtmp1 的大小,要不然一個爛SQL就把磁碟整爆了。
但是MySQL 5.7 之前都沒有解決如下問題:
MySQL 8.0 開始,專門實現了一個臨時表的引擎 TempTable , 解決了 VARCHAR欄位的邊長存儲以及大對象的內存存儲。由變數 interal_tmp_mem_storage_engine來控制,可選值為 TempTable(默認)和 Memory;新引擎的大小由參數temp_table_max_ram 來控制,默認為1G。超過了則存儲在磁碟上(ibtmp1)。並且計數器由性能字典的表 memory_summary_global_by_event_name 來存儲。
以上 memory/temptable/physical_disk 代表放入磁碟上的臨時表計數情況。
memory/temptable/physical_ram 代表放入內存的臨時表計數情況。
那總結下MySQL 8.0 引入的 TempTable 引擎:
3. mysql 創建存儲過程。
/*先建表stugra*/
CREATE TABLE `stugra` (
`name` CHAR(20) DEFAULT NULL,
`mark` INT(3) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=gbk
INSERT INTO stugra VALUES ('aa','59');
INSERT INTO stugra VALUES ('fa','11');
INSERT INTO stugra VALUES ('aga','99');
INSERT INTO stugra VALUES ('v','32');
INSERT INTO stugra VALUES ('da','77');
INSERT INTO stugra VALUES ('gf','44');
INSERT INTO stugra VALUES ('sadf','0');
INSERT INTO stugra VALUES ('eef','32');
INSERT INTO stugra VALUES ('ggg','60');
存儲過程:
DELIMITER $$
DROP PROCEDURE IF EXISTS `pro_find`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `pro_find`()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE a,b INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT mark FROM stugra;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
OPEN cur1;
REPEAT
FETCH cur1 INTO a;
IF NOT done THEN
IF a<60 THEN
SET b=b+1;
END IF;
ELSE
SELECT b;
END IF;
UNTIL done END REPEAT;
CLOSE cur1;
END$$
DELIMITER ;
沒使用count ,使用了循環和選擇,還使用了游標,沒說不能使用游標吧!
4. mysql 在存儲過程中創建表格
DELIMITER$$
USE`test`$$
DROPPROCEDUREIFEXISTS`p_create_table`$$
CREATEDEFINER=`root`@`localhost`PROCEDURE`p_create_table`()
BEGIN
DECLAREtableNameVARCHAR(100);
DECLAREtable_nameVARCHAR(100);
DECLAREmonthIntINTDEFAULT1;
DECLAREmonthStrVARCHAR(16);
DECLAREtableHeaderVARCHAR(16);
DECLAREtableBodyVARCHAR(255);
DECLAREdropTableStrVARCHAR(255);
DECLAREsqlStrVARCHAR(1000);
SETtableName=CONCAT('test_',DATE_FORMAT(NOW(),'%Y'));
SETtableHeader='CREATETABLE';
SETtableBody='(`id`INT(11)NOTNULLAUTO_INCREMENT,`name`VARCHAR(10),PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8;';
WHILEmonthInt<=12DO
IFmonthInt<10THEN
SETmonthStr=CONCAT('0',monthInt);
ELSE
SETmonthStr=CONCAT(monthInt);
ENDIF;
SETtable_name=CONCAT(tableName,monthStr);
SETdropTableStr=CONCAT('DROPTABLEIFEXISTS',table_name);
SETsqlStr=CONCAT(tableHeader,table_name,tableBody);
SELECTdropTableStrINTO@dropTableStr;
SELECTsqlStrINTO@sqlStr;
BEGIN
PREPAREstepDropExistTableFROM@dropTableStr;
EXECUTEstepDropExistTable;
PREPAREstepCreateTbaleFROM@sqlStr;
EXECUTEstepCreateTbale;
END;
SETmonthInt=monthInt+1;
ENDWHILE;
END$$
DELIMITER;
5. Mysql用存儲過程分表
你這樣拆分會建立無數張表,你不確定供應商ID有多少,也就意味著你不知道要建立多少張表,在查詢的時候也需要判斷哪個商品區哪個表查詢,如果只有條碼,或者商品名字怎麼查詢,效果可能得不償失。
建議:1.如果是商品 欄位卻很長,表佔用空間很大,檢索表的時候需要執行大量的IO,嚴重降性能。這時需要把大的欄位拆分到另一個表,並且該表與原表是一對一的關系。也就是把不常用的欄位丟在另外一張表上去
2.如果數據量太多(我想哪怕大超市系統數據量也不會很多,建議採用1),可以根據條碼或者名字拆分,已條碼為例 條碼為1的建立goods_one表
建表語句INSERT INTO goods_one(欄位) SELECT 欄位 FROM goodsWHERE 你的條件
如果你確實要執行你的想法
創建存儲過程
CREATE PROCEDURE 。。。
begin
定義參數(游標)
查詢所有供應商
游標遍歷 更具供應商 查詢goods表
創建表 插入數據
end
最好開啟事務
能幫的就這么多了 望採納
6. mysql為四個表創建儲存過程或者儲存函數
「另一個存儲過程」的名字是sp1,沒有參數,返回的結果集共3列,全部為int型,那麼「存儲過程」里添加一個與結果集列數相同的臨時表或表變數用於接收「另一個存儲過程」的結果集
如下
CREATE
PROCEDURE
sp2
AS
DECLARE
@t
table(a
int,b
int,c
int)
INSERT
INTO
@t(a,b,c)
EXEC
sp1
SELECT
*
FROM
@t
使用SQLSERVER存儲過程可以很大的提高程序運行速度,簡化編程維護難度,現已得到廣泛應用。
創建存儲過程
和數據表一樣,在使用之前需要創建存儲過程,它的簡明語法是:
引用:
Create
PROC
存儲過程名稱
[參數列表(多個以「,」分隔)]
AS
SQL
語句
例:
引用:
Create
PROC
upGetUserName
@intUserId
INT,
@ostrUserName
NVARCHAR(20)
OUTPUT
--
要輸出的參數
AS
BEGIN
--
將uName的值賦給
@ostrUserName
變數,即要輸出的參數
Select
@ostrUserName=uName
FROM
uUser
Where
uId=@intUserId
END
其中
Create
PROC
語句(完整語句為Create
PROCEDURE)的意思就是告訴SQL
SERVER,現在需要建立一個存儲過程,upGetUserName
就是存儲過程名稱,@intUserId
和
@ostrUserName
分別是該存儲過程的兩個參數,注意,在SQL
SERVER中,所有用戶定義的變數都以「@」開頭,OUTPUT關鍵字表示這個參數是用來輸出的,AS之後就是存儲過程內容了。只要將以上代碼在「查詢分析器」里執行一次,SQL
SERVER就會在當前資料庫中創建一個名為「upGetUserName」的存儲過程。你可以打開「企業管理器」,選擇當前操作的資料庫,然後在左邊的樹型列表中選擇「存儲過程」,此時就可以在右邊的列表中看到你剛剛創建的存儲過程了(如果沒有,刷新一下即可)。
7. mysql存儲過程操作表
1. select nameid,case value when 4 then count(*) else 0 end as value1,case value when 3 then count(*) else 0 end as value2 into 新表 from 表 group by nameid,value
2. create proc dbo.名儲過程名稱 As
create table 新表(nameid int,value1 int,value12 int)
insert into 新表(nameid,value1,value12)
select nameid,case bi when 1 then sum(value) else 0 end,case bi when 0 then sum(value) else 0 end from 表 group by nameid