华为云用户手册

  • 示例:从MySQL向 GaussDB (DWS)进行数据迁移 下面示例演示如何通过CopyManager从mysql向GaussDB(DWS)进行数据迁移的过程。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 //以下用例以gsjdbc4.jar为例,如果要使用gsjdbc200.jar,请替换驱动类名(将代码中的“org.postgresql”替换成“com.huawei.gauss200.jdbc”)与连接URL串前缀(将“jdbc:postgresql”替换为“jdbc:gaussdb”)。 import java.io.StringReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.postgresql.copy.CopyManager; import org.postgresql.core.BaseConnection; public class Migration{ public static void main(String[] args) { String url = new String("jdbc:postgresql://10.180.155.74:8000/gaussdb"); //数据库URL String user = new String("jack"); //DWS用户名 String pass = new String("********"); //DWS密码 String tablename = new String("migration_table"); //定义表信息 String delimiter = new String("|"); //定义分隔符 String encoding = new String("UTF8"); //定义字符集 String driver = "org.postgresql.Driver"; StringBuffer buffer = new StringBuffer(); //定义存放格式 化数据的缓存 try { //获取源数据库查询结果集 ResultSet rs = getDataSet(); //遍历结果集,逐行获取记录 //将每条记录中各字段值,按指定分隔符分割,由换行符结束,拼成一个字符串 //把拼成的字符串,添加到缓存buffer while (rs.next()) { buffer.append(rs.getString(1) + delimiter + rs.getString(2) + delimiter + rs.getString(3) + delimiter + rs.getString(4) + "\n"); } rs.close(); try { //建立目标数据库连接 Class.forName(driver); Connection conn = DriverManager.getConnection(url, user, pass); BaseConnection baseConn = (BaseConnection) conn; baseConn.setAutoCommit(false); //初始化表信息 String sql = "Copy " + tablename + " from STDIN DELIMITER " + "'" + delimiter + "'" + " ENCODING " + "'" + encoding + "'"; //提交缓存buffer中的数据 CopyManager cp = new CopyManager(baseConn); StringReader reader = new StringReader(buffer.toString()); cp.copyIn(sql, reader); baseConn.commit(); reader.close(); baseConn.close(); } catch (ClassNotFoundException e) { e.printStackTrace(System.out); } catch (SQLException e) { e.printStackTrace(System.out); } } catch (Exception e) { e.printStackTrace(); } } //******************************** // 从源数据库返回查询结果集 //********************************* private static ResultSet getDataSet() { ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver").newInstance(); Connection conn = DriverManager.getConnection("jdbc:mysql://10.119.179.227:3306/jack?useSSL=false&allowPublicKeyRetrieval=true", "jack", "********"); Statement stmt = conn.createStatement(); rs = stmt.executeQuery("select * from migration_table"); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return rs; } } 父主题: 基于JDBC开发
  • 原型 1 2 3 4 5 6 SQLRETURN SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_IndPtr);
  • 参数 表1 SQLBindCol参数 关键字 参数说明 StatementHandle 语句句柄。 ColumnNumber 要绑定结果集的列号。起始列号为0,以递增的顺序计算列号,第0列是书签列。若未设置书签页,则起始列号为1。 TargetType 缓冲区中C数据类型的标识符。 TargetValuePtr 输出参数:指向与列绑定的数据缓冲区的指针。SQLFetch函数返回这个缓冲区中的数据。如果此参数为一个空指针,则StrLen_or_IndPtr是一个有效值。 BufferLength TargetValuePtr指向缓冲区的长度,以字节为单位。 StrLen_or_IndPtr 输出参数:缓冲区的长度或指示器指针。若为空值,则未使用任何长度或指示器值。
  • 参数 表1 SQLConnect参数 关键字 参数说明 ConnectionHandle 连接句柄,通过SQLAllocHandle获得。 ServerName 要连接数据源的名称。 NameLength1 ServerName的长度。 UserName 数据源中数据库用户名。 NameLength2 UserName的长度。 Authentication 数据源中数据库用户密码。 NameLength3 Authentication的长度。
  • 原型 1 2 3 4 5 6 7 SQLRETURN SQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *ServerName, SQLSMALLINT NameLength1, SQLCHAR *UserName, SQLSMALLINT NameLength2, SQLCHAR *Authentication, SQLSMALLINT NameLength3);
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 --创建存储过程proc_staffs CREATE OR REPLACE PROCEDURE proc_staffs ( section NUMBER(6), salary_sum out NUMBER(8,2), staffs_count out INTEGER ) IS BEGIN SELECT sum(salary), count(*) INTO salary_sum, staffs_count FROM staffs where section_id = section; END; / --创建存储过程proc_return. CREATE OR REPLACE PROCEDURE proc_return AS v_num NUMBER(8,2); v_sum INTEGER; BEGIN proc_staffs(30, v_sum, v_num); --调用语句 dbms_output.put_line(v_sum||'#'||v_num); RETURN; --返回语句 END; / --调用存储过程proc_return. CALL proc_return(); --清除存储过程 DROP PROCEDURE proc_staffs; DROP PROCEDURE proc_return; --创建函数func_return. CREATE OR REPLACE FUNCTION func_return returns void language plpgsql AS $$ DECLARE v_num INTEGER := 1; BEGIN dbms_output.put_line(v_num); RETURN; --返回语句 END $$; -- 调用函数func_return CALL func_return(); 1 -- 清除函数 DROP FUNCTION func_return;
  • 语法 创建函数时需要指定返回值SETOF datatype。 return_next_clause::= return_query_clause::= 对以上语法的解释如下: 当需要函数返回一个集合时,使用RETURN NEXT或者RETURN QUERY向结果集追加结果,然后继续执行函数的下一条语句。随着后续的RETURN NEXT或RETURN QUERY命令的执行,结果集中会有多个结果。函数执行完成后会一起返回所有结果。 RETURN NEXT可用于标量和复合数据类型。 RETURN QUERY有一种变体RETURN QUERY EXECUTE,后面还可以增加动态查询,通过USING向查询插入参数。
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 CREATE TABLE t1(a int); INSERT INTO t1 VALUES(1),(10); --RETURN NEXT CREATE OR REPLACE FUNCTION fun_for_return_next() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN FOR r IN select * from t1 LOOP RETURN NEXT r; END LOOP; RETURN; END; $$ LANGUAGE PLPGSQL; call fun_for_return_next(); a --- 1 10 (2 rows) -- RETURN QUERY CREATE OR REPLACE FUNCTION fun_for_return_query() RETURNS SETOF t1 AS $$ DECLARE r t1%ROWTYPE; BEGIN RETURN QUERY select * from t1; END; $$ language plpgsql; call fun_for_return_next(); a --- 1 10 (2 rows)
  • 冷热数据简介 海量大数据场景下,随着业务和数据量的不断增长,数据存储与消耗的资源也日益增长。根据业务系统中用户对不同时期数据的不同使用需求,对膨胀的数据本身进行“冷热”分级管理,不仅可以提高数据分析性能还能降低业务成本。 例如,在网络流量分析系统中,用户可能对最近一个月内安全事件和网络访问情况感兴趣,而很少关注几个月前的数据。针对这样的一些场景,可以将数据按照时间分为:热数据、冷数据。 冷热数据主要从数据访问频率、更新频率进行划分。 Hot(热数据):访问、更新频率较高,未来被调用的概率较高的数据,对访问的响应时间要求很高的数据。 Cold(冷数据):不允许更新或更新频率比较低,访问频率比较低,对访问的响应时间要求不高的数据。 用户可以定义冷热管理表,将符合规则的冷数据切换至OBS上进行存储,可以按照分区自动进行冷热数据的判断和迁移。
  • 冷热数据管理支持功能 支持对冷热表的insert、copy、delete、update、select等表相关的DML操作。 支持对冷热表的权限管理等DCL操作。 支持对冷热表进行analyze、vacuum、merge into等操作和一些分区的操作。 支持从普通列存分区表升级为冷热数据表。 支持带有冷热数据管理表的升级、扩容、缩容和重分布。 支持冷热分区互相转换。该功能仅8.3.0及以上版本支持。
  • 冷热切换策略 目前冷热切换的策略名称支持LMT(last modify time)和HPN(hot partition number),LMT指按分区的最后更新时间切换,HPN指保留热分区的个数切换。 LMT:表示切换[day]时间前修改的热分区数据为冷分区,将该数据迁至OBS表空间中。其中[day]为整型,范围[0,36500],单位为天。 如下图中,设置day为2,即在冷热切换时,根据分区数据的最晚修改时间,保留2日内所修改的分区为热分区,其余数据为冷分区数据。假设当前时间为4月30日,4月30日对[4-26]分区进行了delete操作,4月29日对[4-27]分区进行了insert操作,故在冷热切换时,保留[4-26][4-27][4-29][4-30]四个分区为热分区。 HPN:表示保留HPN个有数据的分区为热分区。分区顺序按照分区的Sequence ID来确定,分区的Sequence ID是根据分区边界值的大小,内置生成的序号,此序号不对外呈现。对于RANGE分区,分区的边界值越大,分区对应的Sequence ID越大;对于LIST分区,分区边界枚举值中的最大值越大,分区对应的Sequence ID越大。在冷热切换时,需要将数据迁移至OBS表空间中。其中HPN为整型,范围为[0,1600]。其中HPN为0时,表示不保留热分区,在进行冷热切换时,将所有有数据的分区都转为冷分区并存储在OBS上。 如下图中,设置HPN为3,即在冷热切换时,保留最新的3个有数据的分区为热分区数据,其余分区均切为冷分区。
  • 使用示例 创建列存冷热数据管理表,指定热数据有效期LMT为100天。 1 2 3 4 5 6 7 8 CREATE TABLE lifecycle_table(i int, val text) WITH (ORIENTATION = COLUMN, storage_policy = 'LMT:100') PARTITION BY RANGE (i) ( PARTITION P1 VALUES LESS THAN(5), PARTITION P2 VALUES LESS THAN(10), PARTITION P3 VALUES LESS THAN(15), PARTITION P8 VALUES LESS THAN(MAXVALUE) )ENABLE ROW MOVEMENT; 切换冷数据至OBS表空间。 自动切换:每日0点调度框架自动触发,无需关注切换情况。 可自定义自动切换时间:根据业务情况调整自动触发时间,修改为每天早晨6点30分。 1 SELECT * FROM pg_obs_cold_refresh_time('lifecycle_table', '06:30:00'); 手动切换。 执行如下操作手动切换单表: 1 ALTER TABLE lifecycle_table refresh storage; 执行如下操作批量切换所有冷热表: 1 SELECT pg_catalog.pg_refresh_storage(); 将冷分区数据转换成热分区。该功能仅8.3.0及以上版本支持。 将冷热表的所有冷分区转换成热分区: 1 SELECT pg_catalog.reload_cold_partition('lifecycle_table'); 将冷热表的指定冷分区转换成热分区: 1 SELECT pg_catalog.reload_cold_partition('lifecycle_table', 'cold_partition_name'); 查看冷热表数据分布情况。 查看单表数据分布情况: 1 SELECT * FROM pg_catalog.pg_lifecycle_table_data_distribute('lifecycle_table'); 查看所有冷热表数据分布情况: 1 SELECT * FROM pg_catalog.pg_lifecycle_node_data_distribute();
  • 冷热数据管理的约束限制 目前冷热表只支持列存2.0版本的分区表,外表不支持冷热分区。 对于已经切冷分区再次插入数据,数据直接会进入OBS,不会改变分区的冷热属性。 对于同一分区在同一DN只会存在冷或热的一种情况,对于同一分区在不同DN可能存在部分DN为热数据,部分DN为冷数据。 对于同时存在冷热分区的表,查询时会变慢,因为冷数据存储在OBS上,读写速度和时延都比在本地查询要慢。 只支持修改冷热表的冷热切换策略,不支持修改冷热表的冷数据的表空间。 冷热表的分区操作约束: 不支持对冷分区的数据进行exchange操作。 Merge partition分区只支持热分区和热分区合并、冷分区和冷分区合并,不支持冷热分区合并。 ADD/Merge/Split Partition等分区操作不支持指定表空间为OBS表空间。 不支持创建时指定和修改冷热表分区的表空间。 冷热切换不是只要满足条件就立刻进行冷热数据切换,依赖用户手动调用切换命令,或者通过调度器调用切换命令后才真正进行数据切换。目前自动调度时间为每日0点,可进行修改。 目前冷热切换规则只支持LMT和HPN两种。 冷热数据表不支持物理细粒度备份和恢复,由于物理备份时只备份热数据,在备份恢复前后OBS上冷数据为同一份,不支持truncate和drop table等涉及删除文件操作语句的备份恢复操作。
  • 返回值 SQL_SUC CES S:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_NEED_DATA:表示在执行SQL语句前没有提供足够的参数。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_NO_DATA:表示SQL语句不返回结果集。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 SQL_STILL_EXECUTING:表示语句正在执行。
  • 示例 下面列举了基本的匿名块程序: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 --空语句块 BEGIN NULL; END; / --将信息打印到控制台: BEGIN dbms_output.put_line('hello world!'); END; / --将变量内容打印到控制台: DECLARE my_var VARCHAR2(30); BEGIN my_var :='world'; dbms_output.put_line('hello'||my_var); END; /
  • 返回值 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_NEED_DATA:在执行SQL语句前没有提供足够的参数。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 SQL_STILL_EXECUTING:表示语句正在执行。 SQL_NO_DATA:表示SQL语句不返回结果集。
  • 原型 1 2 3 4 5 6 7 SQLRETURN SQLColAttribute(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, SQLPOINTER CharacterAtrriburePtr, SQLSMALLINT BufferLength, SQLSMALLINT *StringLengthPtr, SQLPOINTER NumericAttributePtr);
  • 参数 表1 SQLColAttribute参数 关键字 参数说明 StatementHandle 语句句柄。 ColumnNumber 要检索字段的列号,起始为1,依次递增。 FieldIdentifier IRD中ColumnNumber行的字段。 CharacterAttributePtr 输出参数:一个缓冲区指针,返回FieldIdentifier字段值。 BufferLength 如果FieldIdentifier是一个ODBC定义的字段,而且CharacterAttributePtr指向一个字符串或二进制缓冲区,则此参数为该缓冲区的长度。 如果FieldIdentifier是一个ODBC定义的字段,而且CharacterAttributePtr指向一个整数,则会忽略该字段。 StringLengthPtr 输出参数:缓冲区指针,存放*CharacterAttributePtr中字符类型数据的字节总数,对于非字符类型,忽略BufferLength的值。 NumericAttributePtr 输出参数:指向一个整型缓冲区的指针,返回IRD中ColumnNumber行FieldIdentifier字段的值。
  • 原型 1 2 3 4 SQLRETURN SQLSetStmtAttr(SQLHSTMT StatementHandle SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
  • 参数 表1 SQLSetStmtAttr参数 关键字 参数说明 StatementtHandle 语句句柄。 Attribute 需设置的属性。 ValuePtr 指向对应Attribute的值。依赖于Attribute的值,ValuePtr可能是32位无符号整型值,或指向以空结束的字符串,二进制缓冲区,或者驱动定义值。注意,如果ValuePtr参数是驱动程序指定值。ValuePtr可能是有符号的整数。 StringLength 如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength。
  • 变量声明 变量声明语法请参见图1。 图1 declare_variable::= 对以上语法格式的解释如下: variable_name,为变量名。 type,为变量类型。 value,是该变量的初始值(如果不给定初始值,则初始为NULL)。value也可以是表达式。 示例 1 2 3 4 5 6 DECLARE emp_id INTEGER := 7788; --定义变量并赋值 BEGIN emp_id := 5*7784; --变量赋值 END; /
  • %TYPE属性 %TYPE主要用于声明某个与其他变量类型(例如,表中某列的类型)相同的变量。假如想定义一个my_name变量,它的变量类型与employee的firstname类型相同,可使用如下定义: my_name employee.firstname%TYPE 这样定义可以带来两个好处,首先,不用预先知道employee表的firstname类型具体是什么。其次,即使之后firstname类型有了变化,也不需要再次修改my_name的类型。
  • 变量作用域 变量的作用域表示变量在代码块中的可访问性和可用性。只有在它的作用域内,变量才有效。 变量必须在declare部分声明,即必须建立BEGIN-END块。块结构也强制变量必须先声明后使用,即变量在过程内有不同作用域、不同的生存期。 同一变量可以在不同的作用域内定义多次,内层的定义会覆盖外层的定义。 在外部块定义的变量,可以在嵌套块中使用。但外部块不能访问嵌套块中的变量。 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 DECLARE emp_id INTEGER :=7788; --定义变量并赋值 outer_var INTEGER :=6688; --定义变量并赋值 BEGIN DECLARE emp_id INTEGER :=7799; --定义变量并赋值 inner_var INTEGER :=6688; --定义变量并赋值 BEGIN dbms_output.put_line('inner emp_id ='||emp_id); --显示值为7799 dbms_output.put_line('outer_var ='||outer_var); --引用外部块的变量 END; dbms_output.put_line('outer emp_id ='||emp_id); --显示值为7788 END; /
  • 参数 表1 SQLFreeHandle参数 关键字 参数说明 HandleType SQLFreeHandle要释放的句柄类型。必须为下列值之一: SQL_HANDLE_ENV SQL_HANDLE_DBC SQL_HANDLE_STMT SQL_HANDLE_DESC 如果HandleType不是这些值之一,SQLFreeHandle返回SQL_INVALID_HANDLE。 Handle 要释放的句柄。
  • 原型 1 2 3 4 SQLRETURN SQLSetConnectAttr(SQLHDBC ConnectionHandle SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
  • 参数 表1 SQLSetConnectAttr参数 关键字 参数说明 StatementtHandle 连接句柄。 Attribute 设置属性。 ValuePtr 指向对应Attribute的值。依赖于Attribute的值,ValuePtr是32位无符号整型值或指向以空结束的字符串。注意,如果ValuePtr参数是驱动程序指定值。ValuePtr可能是有符号的整数。 StringLength 如果ValuePtr指向字符串或二进制缓冲区,这个参数是*ValuePtr长度,如果ValuePtr指向整型,忽略StringLength。
  • 参数 表1 SQLBindParameter 关键词 参数说明 StatementHandle 语句句柄。 ParameterNumber 参数序号,起始为1,依次递增。 InputOutputType 输入输出参数类型。 ValueType 参数的C数据类型。 ParameterType 参数的SQL数据类型。 ColumnSize 列的大小或相应参数标记的表达式。 DecimalDigits 列的十进制数字或相应参数标记的表达式。 ParameterValuePtr 指向存储参数数据缓冲区的指针。 BufferLength ParameterValuePtr指向缓冲区的长度,以字节为单位。 StrLen_or_IndPtr 缓冲区的长度或指示器指针。若为空值,则未使用任何长度或指示器值。
  • 原型 1 2 3 4 5 6 7 8 9 10 SQLRETURN SQLBindParameter(SQLHSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT InputOutputType, SQLSMALLINT ValuetType, SQLSMALLINT ParameterType, SQLULEN ColumnSize, SQLSMALLINT DecimalDigits, SQLPOINTER ParameterValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_IndPtr);
  • 示例:通过本地文件导入导出数据 在使用JAVA语言基于GaussDB(DWS)进行二次开发时,可以使用CopyManager接口,通过流方式,将数据库中的数据导出到本地文件或者将本地文件导入数据库中,文件格式支持 CS V、TEXT等格式。 样例程序如下,执行时需要加载GaussDB(DWS) jdbc驱动。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 //以下用例以gsjdbc4.jar为例,如果要使用gsjdbc200.jar,请替换驱动类名(将代码中的“org.postgresql”替换成“com.huawei.gauss200.jdbc”)与连接URL串前缀(将“jdbc:postgresql”替换为“jdbc:gaussdb”)。 import java.sql.Connection; import java.sql.DriverManager; import java.io.IOException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.sql.SQLException; import org.postgresql.copy.CopyManager; import org.postgresql.core.BaseConnection; public class Copy{ public static void main(String[] args) { String urls = new String("jdbc:postgresql://10.180.155.74:8000/gaussdb"); //数据库URL String username = new String("jack"); //用户名 String password = new String("********"); //密码 String tablename = new String("migration_table"); //定义表信息 String tablename1 = new String("migration_table_1"); //定义表信息 String driver = "org.postgresql.Driver"; Connection conn = null; try { Class.forName(driver); conn = DriverManager.getConnection(urls, username, password); } catch (ClassNotFoundException e) { e.printStackTrace(System.out); } catch (SQLException e) { e.printStackTrace(System.out); } // 将migration_table查询结果导出到本地文件d:/data.txt try { copyToFile(conn, "d:/data.txt", "(SELECT * FROM migration_table)"); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //将d:/data.txt中的数据导入到migration_table_1中。 try { copyFromFile(conn, "d:/data.txt", migration_table_1); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 将migration_table_1中的数据导出到本地文件d:/data1.txt try { copyToFile(conn, "d:/data1.txt", migration_table_1); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void copyFromFile(Connection connection, String filePath, String tableName) throws SQLException, IOException { FileInputStream fileInputStream = null; try { CopyManager copyManager = new CopyManager((BaseConnection)connection); fileInputStream = new FileInputStream(filePath); copyManager.copyIn("COPY " + tableName + " FROM STDIN", fileInputStream); } finally { if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void copyToFile(Connection connection, String filePath, String tableOrQuery) throws SQLException, IOException { FileOutputStream fileOutputStream = null; try { CopyManager copyManager = new CopyManager((BaseConnection)connection); fileOutputStream = new FileOutputStream(filePath); copyManager.copyOut("COPY " + tableOrQuery + " TO STDOUT", fileOutputStream); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } } 父主题: 基于JDBC开发
  • 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 --创建存储过程proc_staffs CREATE OR REPLACE PROCEDURE proc_staffs ( section NUMBER(6), salary_sum out NUMBER(8,2), staffs_count out INTEGER ) IS BEGIN SELECT sum(salary), count(*) INTO salary_sum, staffs_count FROM staffs where section_id = section; END; / --创建存储过程proc_return. CREATE OR REPLACE PROCEDURE proc_return AS v_num NUMBER(8,2); v_sum INTEGER; BEGIN proc_staffs(30, v_sum, v_num); --调用语句 dbms_output.put_line(v_sum||'#'||v_num); RETURN; --返回语句 END; / --调用存储过程proc_return. CALL proc_return(); --清除存储过程 DROP PROCEDURE proc_staffs; DROP PROCEDURE proc_return; --创建函数func_return. CREATE OR REPLACE FUNCTION func_return returns void language plpgsql AS $$ DECLARE v_num INTEGER := 1; BEGIN dbms_output.put_line(v_num); RETURN; --返回语句 END $$; -- 调用函数func_return CALL func_return(); 1 -- 清除函数 DROP FUNCTION func_return;
共100000条