SpringBoot
java datasource <-> mssql bulk 삽입 (테이블 반환 매개 변수 사용 SQLServerDataTable )
Xmobile
2023. 1. 23. 08:07
테이블 반환 매개 변수 사용
멀티 로우를 데이터 삽입시에 SQLServerDataTable 를 사용하여 한번에 table parameter로 넘기는 방법 넘기는 방법
pom.xml
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.2.1.jre8</version>
</dependency>
controller
List<HashMap<String, Object>> mapList = new ArrayList<>();
for( int i = 0; i < list1.size(); i++ ) {
HashMap<String, Object> paramMap = (HashMap<String, Object>) params.clone();
String key = list1.get(i).get(0);
paramMap.put("x1", list1.get(i).get(1));
paramMap.put("x2", list1.get(i).get(3));
paramMap.put("y1", list2.get(i).get(key).getField1());
paramMap.put("y2", list2.get(i).get(key).getField2());
paramMap.put("z1", list3.get(i).get(key).getField1());
paramMap.put("z2", list3.get(i).get(key).getField2());
mapList.add(paramMap);
}
tsServiceImpl.saveQma003Upload_bulk(mapList);
service
@Autowired
private DataSource dataSource;
table parameter에 row를 add하여 프로시저 호출
public boolean saveUpload_bulk(List<HashMap<String, Object>> mapList) throws SQLServerException {
SQLServerDataTable tvp = new SQLServerDataTable();
// Define metadata for the data table.
tvp.addColumnMetadata("C1" ,java.sql.Types.NVARCHAR);
tvp.addColumnMetadata("C2" ,java.sql.Types.NVARCHAR);
tvp.addColumnMetadata("C3" ,java.sql.Types.NVARCHAR);
tvp.addColumnMetadata("C4" ,java.sql.Types.NVARCHAR);
tvp.addColumnMetadata("C5" ,java.sql.Types.NVARCHAR);
tvp.addColumnMetadata("C6" ,java.sql.Types.NVARCHAR);
for (HashMap<String, Object> params : mapList) {
tvp.addRow(
StringUtil.blankIfNull(params.get("x1")),//c1
StringUtil.blankIfNull(params.get("x2")),//c2
StringUtil.blankIfNull(params.get("y1")),//c3
StringUtil.blankIfNull(params.get("y2")),//c4
StringUtil.blankIfNull(params.get("z1")),//c5
StringUtil.blankIfNull(params.get("z2")),//c6
);
}
String SQL_COMMAND = "{call P_BULK (?)}";
try {
CallableStatement callableStmt = dataSource.getConnection().prepareCall(SQL_COMMAND);
SQLServerPreparedStatement sqlServerStatement = callableStmt.unwrap(SQLServerPreparedStatement.class);
sqlServerStatement.setStructured(1, "TYPE_UP_DATA_VIB_BULK", tvp);
return sqlServerStatement.execute();
} catch (SQLTimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return false;
}
MSSQL
테이블 반환 매개 변수 형식
CREATE TYPE [dbo].[TYPE_UP_DATA_VIB_BULK] AS TABLE(
[C1] [nvarchar](50) NULL,
[C2] [nvarchar](50) NULL,
[C3] [nvarchar](50) NULL,
[C4] [nvarchar](50) NULL,
[C5] [nvarchar](50) NULL,
[C6] [nvarchar](50) NULL
)
프로시저
ALTER PROCEDURE [dbo].[P_BULK]
(
@itblParam TYPE_UP_DATA_VIB_BULK Readonly,
@p_error_code VARCHAR(100) = '' OUTPUT, -- 사용자 에러코드 리턴
@p_row_count INT = 0 OUTPUT, -- 실행/리턴하는 레코드행수
@p_error_note NVARCHAR(100) = '' OUTPUT, -- 사용자 지정 문자열
@p_return_str NVARCHAR(100) = '' OUTPUT, -- 사용자 지정 반환값
@p_error_str NVARCHAR(1000) = '' OUTPUT, -- 오류메세지
@ErrorState VARCHAR(500) = '' OUTPUT, -- 오류번호/심각도/오류상태번호오류발생루틴내의 줄번호
@ErrorProcedure NVARCHAR(200) = '' OUTPUT -- 오류발생 프로시저/트리거
)
AS
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
--select * from UP_DATA_VIB_VURK;
BEGIN
BEGIN TRY
-----------------------------------------------------------------------------------------------------------------------
-- 첫번째 리턴 레코드셋 처리 --첫 번째 Excel Insert
INSERT INTO UP_DATA_VIB_VURK
(C1, C2, C3, C4, C5, C6)
SELECT
C1, C2, C3, C4, C5, C6
FROM @itblParam AS nr;
SELECT @p_row_count = @@ROWCOUNT
-- 에러가 없을 경우에 정상적인 처리 진행
IF @p_row_count > 0
SET @p_error_code = 'MSG0002' -- 정상적으로 등록되었습니다.
ELSE
SET @p_error_code = 'MSG0029' -- 등록된 레코드가 없습니다.
-----------------------------------------------------------------------------------------------------------------------
END TRY
BEGIN CATCH
SELECT @p_error_code = CASE SUBSTRING('N',1,1)
WHEN 'Q' THEN 'ERR0006' -- 조회시 에러가 발생하였습니다.
WHEN 'N' THEN 'ERR0008' -- 등록시 오류가 발생하였습니다.
WHEN 'U' THEN 'ERR0009' -- 수정시 오류가 발생하였습니다.
WHEN 'D' THEN 'ERR0010' -- 삭제시 오류가 발생하였습니다.
ELSE 'ERR0000'
END
SELECT @ErrorState = CONVERT(VARCHAR(100), ERROR_NUMBER()) + '|' + CONVERT(VARCHAR(100), ERROR_SEVERITY()) + '|' + CONVERT(VARCHAR(100), ERROR_STATE()) + '|' + CONVERT(VARCHAR(100), ERROR_LINE()),
@ErrorProcedure = 'PRC=' + ERROR_PROCEDURE(), @p_error_str = ERROR_MESSAGE();
END CATCH;
END