Как вызвать сохраненный pro c в базе данных db2 из spark scala - PullRequest
0 голосов
/ 11 июля 2020

Мне нужно вызвать сохраненную pro c в db2, которая принимает 3 аргумента и возвращает целое число. Может ли кто-нибудь помочь мне вызвать этот sp из кода spark Scala. Ниже приведен сохраненный pro c в db2.

CREATE PROCEDURE TEST_PROC(IN V_DATE DATE,IN V_GROUP VARCHAR(20),IN V_FREQ 
VARCHAR(20),IN V_RULE VARCHAR(20), OUT ID INTEGER)
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN
LOCK TABLE CAL_LOG IN EXCLUSIVE MODE;
SET ID = (10+ COALESENCE((SELECT MAX(ID) FROM CAL_LOG WITH UR),0));
INSERT INTO CAL_RESULT(ID,P_DATE,GROUP,FREQ,RULE)
VALUES(ID,V-DATE,V_GROUP,V_FREQ,V_RULE);
COMMIT:
END;

PRO C создан, и он работает, как ожидалось.

Теперь я хочу вызвать этот pro c из искра scala код. Я пытаюсь ввести код ниже

val result = spark.read.format("jdbc")
.options(Map(
"url"-> //the db2 url
"driver" - > // my db2 driver
"user name" - > // username
"password" -> // password
""dbtable" -> "(CALL TEST_PROC('2020-07-08','TEST',''TEST','TEST,?)) as proc_result;"
)).load()

, но фрагмент кода дает ошибку ниже

DB@ SQL Error: SQLCODE=-104, SQLSTATE=42601
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601

Ответы [ 3 ]

0 голосов
/ 11 июля 2020

Я рекомендую ScalikeJDB C

Координаты Maven (Scala 2.11): org.scalikejdbc:scalikejdbc_2.11:3.4.1

import scalikejdbc._

// Initialize JDBC driver & connection pool
Class.forName(<db2 driver>)
ConnectionPool.singleton(<url>, <user>, <password>)

// ad-hoc session provider on the REPL
implicit val session = AutoSession 

// Now you can run anything you want
sql"""
CREATE PROCEDURE TEST_PROC(IN V_DATE DATE,IN V_GROUP VARCHAR(20),IN V_FREQ 
VARCHAR(20),IN V_RULE VARCHAR(20), OUT ID INTEGER)
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN
LOCK TABLE CAL_LOG IN EXCLUSIVE MODE;
SET ID = (10+ COALESENCE((SELECT MAX(ID) FROM CAL_LOG WITH UR),0));
INSERT INTO CAL_RESULT(ID,P_DATE,GROUP,FREQ,RULE)
VALUES(ID,V-DATE,V_GROUP,V_FREQ,V_RULE);
COMMIT:
END;""".execute.apply()

Получить данные следующим образом

sql"""(CALL TEST_PROC('2020-07-08','TEST',''TEST','TEST,?)) 
as proc_result;""".execute.apply()

При необходимости результат можно снова превратить в фрейм данных.

0 голосов
/ 11 июля 2020

Вы не можете вызвать хранимую процедуру, используя Apache Spark, хотя загружать те же данные, используя Spark load

Load fron db2

val sqlContext = new org.apache.spark.sql.SQLContext(sc)

val df= sqlContext.load("jdbc", Map(
                       "url" -> "jdbc:db2://xx.xx.xx.xx:50000/SQLDB:securityMechanism=9;currentSchema=vaquarkhan;user=<ur-username>;password=xxxxx;",
        "driver" -> "com.ibm.db2.jcc.DB2Driver",
        "dbtable" -> "scheam.TableName"))

Создайте временную таблицу / df и добавьте фильтры, чтобы получить требуемый ответ .

0 голосов
/ 11 июля 2020

Я думаю, вам следует использовать соединение JDB C напрямую вместо Spark, поскольку ваша хранимая процедура возвращает только целое число. Если вам нужно это значение, вы можете получить его из вызова хранимой процедуры, но используя Scala без использования Spark.

Вы можете найти образец в https://www.ibm.com/support/knowledgecenter/SSEPEK_12.0.0/java/src/tpc/imjcc_tjvcscsp.html

Это стандартный способ вызвать его на любом языке:

  • Если вам нужно заменить параметры, вы можете использовать prepareCall, как описано по ссылке выше
  • назначить параметры значения с помощью параметра registerParameter (In или Out)
  • запустите executeQuery, поскольку ваш sp возвращает целое число
  • закрыть соединение
...