/* * Microsoft JDBC Driver for SQL Server * * Copyright(c) Microsoft Corporation All rights reserved. * * This program is made available under the terms of the MIT License. See the LICENSE file in the project root for more information. */ package com.microsoft.sqlserver.jdbc.tvp; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.sql.SQLException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement; import com.microsoft.sqlserver.jdbc.SQLServerDataTable; import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement; import com.microsoft.sqlserver.testframework.AbstractTest; import com.microsoft.sqlserver.testframework.DBConnection; import com.microsoft.sqlserver.testframework.DBResultSet; import com.microsoft.sqlserver.testframework.DBStatement; @RunWith(JUnitPlatform.class) public class TVPSchemaTest extends AbstractTest { private static DBConnection conn = null; static DBStatement stmt = null; static DBResultSet rs = null; static SQLServerDataTable tvp = null; static String expectecValue1 = "hello"; static String expectecValue2 = "world"; static String expectecValue3 = "again"; private static String schemaName = "anotherSchma"; private static String tvpNameWithouSchema = "charTVP"; private static String tvpNameWithSchema = "[" + schemaName + "].[" + tvpNameWithouSchema + "]"; private static String charTable = "[" + schemaName + "].[tvpCharTable]"; private static String procedureName = "[" + schemaName + "].[procedureThatCallsTVP]"; /** * PreparedStatement with storedProcedure * * @throws SQLException */ @Test @DisplayName("TVPSchema_PreparedStatement_StoredProcedure()") public void testTVPSchema_PreparedStatement_StoredProcedure() throws SQLException { final String sql = "{call " + procedureName + "(?)}"; SQLServerPreparedStatement P_C_statement = (SQLServerPreparedStatement) connection.prepareStatement(sql); P_C_statement.setStructured(1, tvpNameWithSchema, tvp); P_C_statement.execute(); rs = stmt.executeQuery("select * from " + charTable); verify(rs); if (null != P_C_statement) { P_C_statement.close(); } } /** * callableStatement with StoredProcedure * * @throws SQLException */ @Test @DisplayName("TVPSchema_CallableStatement_StoredProcedure()") public void testTVPSchema_CallableStatement_StoredProcedure() throws SQLException { final String sql = "{call " + procedureName + "(?)}"; SQLServerCallableStatement P_C_statement = (SQLServerCallableStatement) connection.prepareCall(sql); P_C_statement.setStructured(1, tvpNameWithSchema, tvp); P_C_statement.execute(); rs = stmt.executeQuery("select * from " + charTable); verify(rs); if (null != P_C_statement) { P_C_statement.close(); } } /** * Prepared with InsertCommand * * @throws SQLException * @throws IOException */ @Test @DisplayName("TVPSchema_Prepared_InsertCommand") public void testTVPSchema_Prepared_InsertCommand() throws SQLException, IOException { SQLServerPreparedStatement P_C_stmt = (SQLServerPreparedStatement) connection .prepareStatement("INSERT INTO " + charTable + " select * from ? ;"); P_C_stmt.setStructured(1, tvpNameWithSchema, tvp); P_C_stmt.executeUpdate(); rs = stmt.executeQuery("select * from " + charTable); verify(rs); if (null != P_C_stmt) { P_C_stmt.close(); } } /** * Callable with InsertCommand * * @throws SQLException * @throws IOException */ @Test @DisplayName("TVPSchema_Callable_InsertCommand()") public void testTVPSchema_Callable_InsertCommand() throws SQLException, IOException { SQLServerCallableStatement P_C_stmt = (SQLServerCallableStatement) connection.prepareCall("INSERT INTO " + charTable + " select * from ? ;"); P_C_stmt.setStructured(1, tvpNameWithSchema, tvp); P_C_stmt.executeUpdate(); rs = stmt.executeQuery("select * from " + charTable); verify(rs); if (null != P_C_stmt) { P_C_stmt.close(); } } @BeforeEach private void testSetup() throws SQLException { conn = new DBConnection(connectionString); stmt = conn.createStatement(); dropProcedure(); dropTables(); dropTVPS(); dropAndCreateSchema(); createTVPS(); createTables(); createPreocedure(); tvp = new SQLServerDataTable(); tvp.addColumnMetadata("PlainChar", java.sql.Types.CHAR); tvp.addColumnMetadata("PlainVarchar", java.sql.Types.VARCHAR); tvp.addColumnMetadata("PlainVarcharMax", java.sql.Types.VARCHAR); tvp.addRow(expectecValue1, expectecValue2, expectecValue3); tvp.addRow(expectecValue1, expectecValue2, expectecValue3); tvp.addRow(expectecValue1, expectecValue2, expectecValue3); tvp.addRow(expectecValue1, expectecValue2, expectecValue3); tvp.addRow(expectecValue1, expectecValue2, expectecValue3); } private void verify(DBResultSet rs) throws SQLException { while (rs.next()) { String actualValue1 = rs.getString(1); String actualValue2 = rs.getString(2); String actualValue3 = rs.getString(3); assertTrue(actualValue1.trim().equals(expectecValue1), "actual value does not match expected value." + "\n\tExpected value: " + expectecValue1 + "\n\tActual value: " + actualValue1); assertTrue(actualValue2.trim().equals(expectecValue2), "actual value does not match expected value." + "\n\tExpected value: " + expectecValue2 + "\n\tActual value: " + actualValue2); assertTrue(actualValue3.trim().equals(expectecValue3), "actual value does not match expected value." + "\n\tExpected value: " + expectecValue3 + "\n\tActual value: " + actualValue3); } } private void dropProcedure() throws SQLException { String sql = " IF EXISTS (select * from sysobjects where id = object_id(N'" + procedureName + "') and OBJECTPROPERTY(id, N'IsProcedure') = 1)" + " DROP PROCEDURE " + procedureName; stmt.execute(sql); } private static void dropTables() throws SQLException { stmt.executeUpdate("if object_id('" + charTable + "','U') is not null" + " drop table " + charTable); } private static void dropTVPS() throws SQLException { stmt.executeUpdate("IF EXISTS (SELECT * FROM sys.types WHERE is_table_type = 1 AND name = '" + tvpNameWithouSchema + "') " + " drop type " + tvpNameWithSchema); } private static void dropAndCreateSchema() throws SQLException { stmt.execute("if EXISTS (SELECT * FROM sys.schemas where name = 'anotherSchma') drop schema anotherSchma"); stmt.execute("CREATE SCHEMA anotherSchma"); } private static void createPreocedure() throws SQLException { String sql = "CREATE PROCEDURE " + procedureName + " @InputData " + tvpNameWithSchema + " READONLY " + " AS " + " BEGIN " + " INSERT INTO " + charTable + " SELECT * FROM @InputData" + " END"; stmt.execute(sql); } private void createTables() throws SQLException { String sql = "create table " + charTable + " (" + "PlainChar char(50) null," + "PlainVarchar varchar(50) null," + "PlainVarcharMax varchar(max) null," + ");"; stmt.execute(sql); } private void createTVPS() throws SQLException { String TVPCreateCmd = "CREATE TYPE " + tvpNameWithSchema + " as table ( " + "PlainChar char(50) null," + "PlainVarchar varchar(50) null," + "PlainVarcharMax varchar(max) null" + ")"; stmt.executeUpdate(TVPCreateCmd); } @AfterEach private void terminateVariation() throws SQLException { if (null != conn) { conn.close(); } if (null != stmt) { stmt.close(); } if (null != rs) { rs.close(); } if (null != tvp) { tvp.clear(); } } }