How to pass a table-valued parameter to a stored procedure using jTDS?
I need to call a stored procedure using JTDS jdbc driver.
But this stored procedure needs a struct type as a parameter.
The Jtds CallableStatement does not have a method that set a struct, so I've tryied cast to a SQLServerCallableStatement and set the structure I want.
The code I use is below
Connection con = ds.getConnection();
CallableStatement call = con.prepareCall("{call getErrosSKF ?,?,?,?}");
call.setString("agrupador", agrupador);
call.setDate(2, new Date(dataInicio.getTimeInMillis()));
call.setDate(3, new Date(dataFim.getTimeInMillis()));
SQLServerDataTable areas = new SQLServerDataTable();
areas.addColumnMetadata("id",Types.INTEGER);
for(Integer a : skfIdAreas) {
areas.addRow(a);
}
// generate an exception
((SQLServerCallableStatement) call).setStructured(4, "erroSKFTable", areas);
But I can't cast because its generate an exception saying that
The JtdsCallableStatement
cannot be cast to SqlServerCallableStatemen
.
Is there an alternative I can use?
java sql-server stored-procedures jdbc jtds
add a comment |
I need to call a stored procedure using JTDS jdbc driver.
But this stored procedure needs a struct type as a parameter.
The Jtds CallableStatement does not have a method that set a struct, so I've tryied cast to a SQLServerCallableStatement and set the structure I want.
The code I use is below
Connection con = ds.getConnection();
CallableStatement call = con.prepareCall("{call getErrosSKF ?,?,?,?}");
call.setString("agrupador", agrupador);
call.setDate(2, new Date(dataInicio.getTimeInMillis()));
call.setDate(3, new Date(dataFim.getTimeInMillis()));
SQLServerDataTable areas = new SQLServerDataTable();
areas.addColumnMetadata("id",Types.INTEGER);
for(Integer a : skfIdAreas) {
areas.addRow(a);
}
// generate an exception
((SQLServerCallableStatement) call).setStructured(4, "erroSKFTable", areas);
But I can't cast because its generate an exception saying that
The JtdsCallableStatement
cannot be cast to SqlServerCallableStatemen
.
Is there an alternative I can use?
java sql-server stored-procedures jdbc jtds
1
I don't think jtds supports table-valued parameters per this 10-year old feature request. The current Microsoft JDBC driver does, though.
– Dan Guzman
Jan 3 at 13:44
Do you know what version of Microsoft JDBC driver is suported by jre1.6?
– makeItEasier
Jan 3 at 14:01
add a comment |
I need to call a stored procedure using JTDS jdbc driver.
But this stored procedure needs a struct type as a parameter.
The Jtds CallableStatement does not have a method that set a struct, so I've tryied cast to a SQLServerCallableStatement and set the structure I want.
The code I use is below
Connection con = ds.getConnection();
CallableStatement call = con.prepareCall("{call getErrosSKF ?,?,?,?}");
call.setString("agrupador", agrupador);
call.setDate(2, new Date(dataInicio.getTimeInMillis()));
call.setDate(3, new Date(dataFim.getTimeInMillis()));
SQLServerDataTable areas = new SQLServerDataTable();
areas.addColumnMetadata("id",Types.INTEGER);
for(Integer a : skfIdAreas) {
areas.addRow(a);
}
// generate an exception
((SQLServerCallableStatement) call).setStructured(4, "erroSKFTable", areas);
But I can't cast because its generate an exception saying that
The JtdsCallableStatement
cannot be cast to SqlServerCallableStatemen
.
Is there an alternative I can use?
java sql-server stored-procedures jdbc jtds
I need to call a stored procedure using JTDS jdbc driver.
But this stored procedure needs a struct type as a parameter.
The Jtds CallableStatement does not have a method that set a struct, so I've tryied cast to a SQLServerCallableStatement and set the structure I want.
The code I use is below
Connection con = ds.getConnection();
CallableStatement call = con.prepareCall("{call getErrosSKF ?,?,?,?}");
call.setString("agrupador", agrupador);
call.setDate(2, new Date(dataInicio.getTimeInMillis()));
call.setDate(3, new Date(dataFim.getTimeInMillis()));
SQLServerDataTable areas = new SQLServerDataTable();
areas.addColumnMetadata("id",Types.INTEGER);
for(Integer a : skfIdAreas) {
areas.addRow(a);
}
// generate an exception
((SQLServerCallableStatement) call).setStructured(4, "erroSKFTable", areas);
But I can't cast because its generate an exception saying that
The JtdsCallableStatement
cannot be cast to SqlServerCallableStatemen
.
Is there an alternative I can use?
java sql-server stored-procedures jdbc jtds
java sql-server stored-procedures jdbc jtds
edited Jan 3 at 17:50
Gord Thompson
78.8k1497225
78.8k1497225
asked Jan 3 at 13:37
makeItEasiermakeItEasier
929
929
1
I don't think jtds supports table-valued parameters per this 10-year old feature request. The current Microsoft JDBC driver does, though.
– Dan Guzman
Jan 3 at 13:44
Do you know what version of Microsoft JDBC driver is suported by jre1.6?
– makeItEasier
Jan 3 at 14:01
add a comment |
1
I don't think jtds supports table-valued parameters per this 10-year old feature request. The current Microsoft JDBC driver does, though.
– Dan Guzman
Jan 3 at 13:44
Do you know what version of Microsoft JDBC driver is suported by jre1.6?
– makeItEasier
Jan 3 at 14:01
1
1
I don't think jtds supports table-valued parameters per this 10-year old feature request. The current Microsoft JDBC driver does, though.
– Dan Guzman
Jan 3 at 13:44
I don't think jtds supports table-valued parameters per this 10-year old feature request. The current Microsoft JDBC driver does, though.
– Dan Guzman
Jan 3 at 13:44
Do you know what version of Microsoft JDBC driver is suported by jre1.6?
– makeItEasier
Jan 3 at 14:01
Do you know what version of Microsoft JDBC driver is suported by jre1.6?
– makeItEasier
Jan 3 at 14:01
add a comment |
1 Answer
1
active
oldest
votes
Support for table-valued parameters (TVPs) is a fairly recent addition to Microsoft's JDBC Driver for SQL Server, and in fact, according to ...
System Requirements for the JDBC Driver
... none of the currently available JDBC drivers from Microsoft will work with JRE_6. You could try and find an ancient JDBC driver from Microsoft, but it wouldn't directly support TVPs anyway, so you might as well stick with jTDS.
Now jTDS doesn't directly support TVPs either, but you can accomplish your task by
- creating a temporary table,
- populating the temporary table with your data, and then
- using an anonymous code block to populate a TVP from the temporary table and then call the stored procedure.
Example:
Given an existing reference table named [phonetic] ...
letter word
------ -------
A Alfa
B Bravo
C Charlie
...
Y Yankee
Z Zulu
... a user-defined table type ...
CREATE TYPE [dbo].[LetterListTableType] AS TABLE(
[seq] [int] NOT NULL,
[letter] [varchar](1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[seq] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
... and a stored procedure that takes that table type as a parameter ...
CREATE PROCEDURE [dbo].[GetPhonetic]
@letters dbo.LetterListTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT l.seq, l.letter, p.word
FROM phonetic p INNER JOIN @letters l on p.letter = l.letter
ORDER BY l.seq;
END
... the following Java code ...
// 0. create some test data
String letters = new String { "G", "o", "r", "d" };
//
// 1. create temporary table
Statement s = conn.createStatement();
s.executeUpdate("CREATE TABLE #tmp (seq INT IDENTITY PRIMARY KEY, letter VARCHAR(1))");
//
// 2. populate temporary table with letters to look up
PreparedStatement ps = conn.prepareStatement("INSERT INTO #tmp (letter) VALUES (?)");
for (String letter : letters) {
ps.setString(1, letter);
ps.addBatch();
}
ps.executeBatch();
//
// 3. use anonymous code block to pass table-valued parameter to stored procedure
String sql =
"SET NOCOUNT ON; "
+ "DECLARE @tvp dbo.LetterListTableType; "
+ "INSERT INTO @tvp (seq, letter) SELECT seq, letter FROM #tmp; "
+ "EXEC dbo.GetPhonetic @tvp; ";
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
System.out.printf("%s -> %s%n", rs.getString("letter"), rs.getString("word"));
}
... produces
G -> Golf
o -> Oscar
r -> Romeo
d -> Delta
Thanks for helping. I didn't think this way.
– makeItEasier
Jan 3 at 18:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54023407%2fhow-to-pass-a-table-valued-parameter-to-a-stored-procedure-using-jtds%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Support for table-valued parameters (TVPs) is a fairly recent addition to Microsoft's JDBC Driver for SQL Server, and in fact, according to ...
System Requirements for the JDBC Driver
... none of the currently available JDBC drivers from Microsoft will work with JRE_6. You could try and find an ancient JDBC driver from Microsoft, but it wouldn't directly support TVPs anyway, so you might as well stick with jTDS.
Now jTDS doesn't directly support TVPs either, but you can accomplish your task by
- creating a temporary table,
- populating the temporary table with your data, and then
- using an anonymous code block to populate a TVP from the temporary table and then call the stored procedure.
Example:
Given an existing reference table named [phonetic] ...
letter word
------ -------
A Alfa
B Bravo
C Charlie
...
Y Yankee
Z Zulu
... a user-defined table type ...
CREATE TYPE [dbo].[LetterListTableType] AS TABLE(
[seq] [int] NOT NULL,
[letter] [varchar](1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[seq] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
... and a stored procedure that takes that table type as a parameter ...
CREATE PROCEDURE [dbo].[GetPhonetic]
@letters dbo.LetterListTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT l.seq, l.letter, p.word
FROM phonetic p INNER JOIN @letters l on p.letter = l.letter
ORDER BY l.seq;
END
... the following Java code ...
// 0. create some test data
String letters = new String { "G", "o", "r", "d" };
//
// 1. create temporary table
Statement s = conn.createStatement();
s.executeUpdate("CREATE TABLE #tmp (seq INT IDENTITY PRIMARY KEY, letter VARCHAR(1))");
//
// 2. populate temporary table with letters to look up
PreparedStatement ps = conn.prepareStatement("INSERT INTO #tmp (letter) VALUES (?)");
for (String letter : letters) {
ps.setString(1, letter);
ps.addBatch();
}
ps.executeBatch();
//
// 3. use anonymous code block to pass table-valued parameter to stored procedure
String sql =
"SET NOCOUNT ON; "
+ "DECLARE @tvp dbo.LetterListTableType; "
+ "INSERT INTO @tvp (seq, letter) SELECT seq, letter FROM #tmp; "
+ "EXEC dbo.GetPhonetic @tvp; ";
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
System.out.printf("%s -> %s%n", rs.getString("letter"), rs.getString("word"));
}
... produces
G -> Golf
o -> Oscar
r -> Romeo
d -> Delta
Thanks for helping. I didn't think this way.
– makeItEasier
Jan 3 at 18:19
add a comment |
Support for table-valued parameters (TVPs) is a fairly recent addition to Microsoft's JDBC Driver for SQL Server, and in fact, according to ...
System Requirements for the JDBC Driver
... none of the currently available JDBC drivers from Microsoft will work with JRE_6. You could try and find an ancient JDBC driver from Microsoft, but it wouldn't directly support TVPs anyway, so you might as well stick with jTDS.
Now jTDS doesn't directly support TVPs either, but you can accomplish your task by
- creating a temporary table,
- populating the temporary table with your data, and then
- using an anonymous code block to populate a TVP from the temporary table and then call the stored procedure.
Example:
Given an existing reference table named [phonetic] ...
letter word
------ -------
A Alfa
B Bravo
C Charlie
...
Y Yankee
Z Zulu
... a user-defined table type ...
CREATE TYPE [dbo].[LetterListTableType] AS TABLE(
[seq] [int] NOT NULL,
[letter] [varchar](1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[seq] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
... and a stored procedure that takes that table type as a parameter ...
CREATE PROCEDURE [dbo].[GetPhonetic]
@letters dbo.LetterListTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT l.seq, l.letter, p.word
FROM phonetic p INNER JOIN @letters l on p.letter = l.letter
ORDER BY l.seq;
END
... the following Java code ...
// 0. create some test data
String letters = new String { "G", "o", "r", "d" };
//
// 1. create temporary table
Statement s = conn.createStatement();
s.executeUpdate("CREATE TABLE #tmp (seq INT IDENTITY PRIMARY KEY, letter VARCHAR(1))");
//
// 2. populate temporary table with letters to look up
PreparedStatement ps = conn.prepareStatement("INSERT INTO #tmp (letter) VALUES (?)");
for (String letter : letters) {
ps.setString(1, letter);
ps.addBatch();
}
ps.executeBatch();
//
// 3. use anonymous code block to pass table-valued parameter to stored procedure
String sql =
"SET NOCOUNT ON; "
+ "DECLARE @tvp dbo.LetterListTableType; "
+ "INSERT INTO @tvp (seq, letter) SELECT seq, letter FROM #tmp; "
+ "EXEC dbo.GetPhonetic @tvp; ";
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
System.out.printf("%s -> %s%n", rs.getString("letter"), rs.getString("word"));
}
... produces
G -> Golf
o -> Oscar
r -> Romeo
d -> Delta
Thanks for helping. I didn't think this way.
– makeItEasier
Jan 3 at 18:19
add a comment |
Support for table-valued parameters (TVPs) is a fairly recent addition to Microsoft's JDBC Driver for SQL Server, and in fact, according to ...
System Requirements for the JDBC Driver
... none of the currently available JDBC drivers from Microsoft will work with JRE_6. You could try and find an ancient JDBC driver from Microsoft, but it wouldn't directly support TVPs anyway, so you might as well stick with jTDS.
Now jTDS doesn't directly support TVPs either, but you can accomplish your task by
- creating a temporary table,
- populating the temporary table with your data, and then
- using an anonymous code block to populate a TVP from the temporary table and then call the stored procedure.
Example:
Given an existing reference table named [phonetic] ...
letter word
------ -------
A Alfa
B Bravo
C Charlie
...
Y Yankee
Z Zulu
... a user-defined table type ...
CREATE TYPE [dbo].[LetterListTableType] AS TABLE(
[seq] [int] NOT NULL,
[letter] [varchar](1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[seq] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
... and a stored procedure that takes that table type as a parameter ...
CREATE PROCEDURE [dbo].[GetPhonetic]
@letters dbo.LetterListTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT l.seq, l.letter, p.word
FROM phonetic p INNER JOIN @letters l on p.letter = l.letter
ORDER BY l.seq;
END
... the following Java code ...
// 0. create some test data
String letters = new String { "G", "o", "r", "d" };
//
// 1. create temporary table
Statement s = conn.createStatement();
s.executeUpdate("CREATE TABLE #tmp (seq INT IDENTITY PRIMARY KEY, letter VARCHAR(1))");
//
// 2. populate temporary table with letters to look up
PreparedStatement ps = conn.prepareStatement("INSERT INTO #tmp (letter) VALUES (?)");
for (String letter : letters) {
ps.setString(1, letter);
ps.addBatch();
}
ps.executeBatch();
//
// 3. use anonymous code block to pass table-valued parameter to stored procedure
String sql =
"SET NOCOUNT ON; "
+ "DECLARE @tvp dbo.LetterListTableType; "
+ "INSERT INTO @tvp (seq, letter) SELECT seq, letter FROM #tmp; "
+ "EXEC dbo.GetPhonetic @tvp; ";
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
System.out.printf("%s -> %s%n", rs.getString("letter"), rs.getString("word"));
}
... produces
G -> Golf
o -> Oscar
r -> Romeo
d -> Delta
Support for table-valued parameters (TVPs) is a fairly recent addition to Microsoft's JDBC Driver for SQL Server, and in fact, according to ...
System Requirements for the JDBC Driver
... none of the currently available JDBC drivers from Microsoft will work with JRE_6. You could try and find an ancient JDBC driver from Microsoft, but it wouldn't directly support TVPs anyway, so you might as well stick with jTDS.
Now jTDS doesn't directly support TVPs either, but you can accomplish your task by
- creating a temporary table,
- populating the temporary table with your data, and then
- using an anonymous code block to populate a TVP from the temporary table and then call the stored procedure.
Example:
Given an existing reference table named [phonetic] ...
letter word
------ -------
A Alfa
B Bravo
C Charlie
...
Y Yankee
Z Zulu
... a user-defined table type ...
CREATE TYPE [dbo].[LetterListTableType] AS TABLE(
[seq] [int] NOT NULL,
[letter] [varchar](1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[seq] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
... and a stored procedure that takes that table type as a parameter ...
CREATE PROCEDURE [dbo].[GetPhonetic]
@letters dbo.LetterListTableType READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT l.seq, l.letter, p.word
FROM phonetic p INNER JOIN @letters l on p.letter = l.letter
ORDER BY l.seq;
END
... the following Java code ...
// 0. create some test data
String letters = new String { "G", "o", "r", "d" };
//
// 1. create temporary table
Statement s = conn.createStatement();
s.executeUpdate("CREATE TABLE #tmp (seq INT IDENTITY PRIMARY KEY, letter VARCHAR(1))");
//
// 2. populate temporary table with letters to look up
PreparedStatement ps = conn.prepareStatement("INSERT INTO #tmp (letter) VALUES (?)");
for (String letter : letters) {
ps.setString(1, letter);
ps.addBatch();
}
ps.executeBatch();
//
// 3. use anonymous code block to pass table-valued parameter to stored procedure
String sql =
"SET NOCOUNT ON; "
+ "DECLARE @tvp dbo.LetterListTableType; "
+ "INSERT INTO @tvp (seq, letter) SELECT seq, letter FROM #tmp; "
+ "EXEC dbo.GetPhonetic @tvp; ";
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
System.out.printf("%s -> %s%n", rs.getString("letter"), rs.getString("word"));
}
... produces
G -> Golf
o -> Oscar
r -> Romeo
d -> Delta
edited Jan 3 at 17:59
answered Jan 3 at 17:50
Gord ThompsonGord Thompson
78.8k1497225
78.8k1497225
Thanks for helping. I didn't think this way.
– makeItEasier
Jan 3 at 18:19
add a comment |
Thanks for helping. I didn't think this way.
– makeItEasier
Jan 3 at 18:19
Thanks for helping. I didn't think this way.
– makeItEasier
Jan 3 at 18:19
Thanks for helping. I didn't think this way.
– makeItEasier
Jan 3 at 18:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54023407%2fhow-to-pass-a-table-valued-parameter-to-a-stored-procedure-using-jtds%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I don't think jtds supports table-valued parameters per this 10-year old feature request. The current Microsoft JDBC driver does, though.
– Dan Guzman
Jan 3 at 13:44
Do you know what version of Microsoft JDBC driver is suported by jre1.6?
– makeItEasier
Jan 3 at 14:01