DECLARE xml and then INSERT INTO table - sql

I have a application thas sends an xml into my db2 stored procedure
In SQL Server the stored procedure is written like this:
DECLARE #startWithDiagnosisNumbers xml
SELECT #startWithDiagnosisNumbers = N'<Ids><id>G43</id><id>G44</id></Ids>'
DECLARE #TEMP_CXP_DiagnosisNumbers TABLE (ID nvarchar(50))
INSERT INTO #TEMP_CXP_DiagnosisNumbers (ID)
SELECT ParamValues.ID.value('.','NVARCHAR(50)')
FROM #startWithDiagnosisNumbers .nodes('/Ids/id') as ParamValues(ID)
How do I translate this over to db2?
I have tried this:
BEGIN
DECLARE startWithDiagnosisNumbers XML;
END
but get error message: "The data type for parameter or SQL variable"STARTWITHDIAGNOSISNUMBERS" is not supported in the routine, compound SQL statement, or parameter list of a cursor value constructor."
And I cant find how to translate the INSERT INTO.
I am very grateful for any help :-)

There are some limitations on the use of XML data type, as described in the manual. Make sure you have the latest fix pack for your version and try to write your code as a stored procedure instead of a simple compound SQL statement (a.k.a. anonymous block).
To extract data from the XML document in a table form you can use the XMLTABLE function -- check examples in the manual.
PS. Using SQL Server-centric approaches such as extensive use of temporary tables isn't necessarily the most efficient way of accomplish things in DB2.

Related

How to insert a sql script in a table column?

How to insert a sql script in a table column?
I have a table column which has ntext datatype. I will have to insert the whole function or stored procedure in the column.
Giving an example : sp_helptext 'sp_TestProcedure' will return the complete syntax of a stored procedure. How to populate the stored procedure script in a Table.
I can change the data type either ntext or nvarchar(max). Actual question is , how to insert the script in a column ?
This is not an insert of stored procedure result. This script which i am looking for is to insert the actual stored procedure (or) function (or) view in a table
You could take a look at sys.sql_modules, which contains definitions (code) for database objects.
INSERT INTO [dbo].[some_table] ([schema_name], [object_name], [definition])
SELECT
OBJECT_SCHEMA_NAME([object_id]) [schema_name],
OBJECT_NAME([object_id]) [object_name],
[definition]
FROM sys.sql_modules
WHERE OBJECT_SCHEMA_NAME([object_id]) = 'dbo'
AND OBJECT_NAME([object_id]) = 'some_object'
Update: As others have commented, if the purpose is to maintain version history it may be more effective to use some other source code control solution. Also, if you want to track any time code in database objects change you could look into implementing a DDL trigger. Just searching "ddl trigger to track schema changes" produced some promising results.
Also, I just stumbled across OBJECT_DEFINITION(), which may be helpful:
SELECT OBJECT_DEFINITION(OBJECT_ID('dbo.spt_values'))
script is text. simply use the regular 'insert into' that sql server has.
when that script is inside a file, you need to read the contents of that file first. the method of doing that depends on the type of language you use - c, c#, java or python (whichever).
if you want to retrieve it, use the normal 'select' command.
however, I do not believe it's a good way of storing functions. being inside a file-system works (usually).

Selecting data from a different schema within a stored procedure

Consider this:
CREATE PROCEDURE [dbo].[setIdentifier](#oldIdentifierName as varchar(50), #newIdentifierName as varchar(50))
AS
BEGIN
DECLARE #old_id as int;
DECLARE #new_id as int;
SET #old_id = (SELECT value FROM Configuration WHERE id = #oldIdentifierName);
SET #new_id = (SELECT value FROM Configuration WHERE id = #newIdentifierName);
IF #old_id IS NOT NULL AND #new_id IS NOT NULL
BEGIN
UPDATE Customer
SET type = #new_id
WHERE type = #old_id;
END;
END
[...]
EXECUTE dbo.setIdentifier '1', '2';
What this does is create a stored procedure that accepts two parameters which it then uses to update a Customer table.
The problem is that the entire script above runs within a schema other than "dbo". Let's just assume the schema is "company1". And when the stored procedure is called, I get an error from the SELECT statement, which says that the Configuration table cannot be found. I'm guessing this is because MS SQL by default looks for tables within the same schema as the location of the stored procedure, and not within the calling context.
My question is this:
Is there some option or parameter or switch of some kind that will
tell MS SQL to look for tables in the "caller's default schema" and
not within the schema that procedure itself is stored in?
If not,
what would you recommend? I don't really want to prefix the tables
with the schema name, because it would be kind of unflexible to do
that. So I'm thinking about using dynamic sql (and the schema_name()
function which returns the correct value even within the procedure),
but I am just not experienced enough with MS SQL to construct the
proper syntax.
It would be a tad more efficient to explicitly specify the schema name. And generally speaking, schema's are mainly used to divide a database into logical area's. I would not anticipate on tables schema-hopping often.
Regarding your question, you might want to have a look at the 'execute as' documentation on msdn, since it allows to explicitly control your execution context.
I ended up passing the schema name to my script as a property on the command line for the "sqlcmd" command. Like this:
C:/> sqlcmd -vSCHEMANAME=myschema -imysqlfile
In the SQL script I can then access this variable like this:
SELECT * from $(SCHEMANAME).myTable WHERE.... etc
Not quite as flexible as dynamic sql, but "good enough" as it were.
Thanks all for taking time to respond.

SQL stored procedure where database to query is parameter

I am working with Microsoft Access (not SQL server) and have written a stored procedure (Query) as shown below in SQL.
This procedure works but it relies on a hard coded path to the database from which to pull (SELECT) the data.
To make the query more useful I want to pass the database to SELECT from as a parameter to the query - how does one do this?
INSERT INTO Part_Batteries ( ItemCode, Size, Voltage )
SELECT tblBatteries.ItemCode, tblBatteries.SizeAH, tblBatteries.Voltage
FROM tblBatteries IN 'C:\Databases\DeviceDatabases\UKDevices.mdb';
I.e. I want to replace the line
FROM tblBatteries IN 'C:\Databases\DeviceDatabases\UKDevices.mdb';
with something like this
FROM tblBatteries IN #DB
Currently I am testing the procedures by either clicking on them in Access or by calling them from a VB module.
When I am satisfied they work I will call them as required from the main application that will be built using C#.
Thanks in advance.
Please read this http://www.sommarskog.se/dynamic_sql.html#storedprocedures
I think it is what you are looking for.
You need to declare the variable at the top of your stored proc
DECLARE #DB AS string
INSERT INTO Part_Batteries ( ItemCode, Size, Voltage )
SELECT tblBatteries.ItemCode, tblBatteries.SizeAH, tblBatteries.Voltage
FROM tblBatteries IN #DB;

INSERT INTO #table_name...EXEC usp_name

I've read in a lot of web sites that the following code will not work, where #table_name is a table variable:
INSERT INTO #table_name EXEC usp_name usp_param1, usp_param2
But the above exact code works fine for me inside a stored procedure in SQL Server 2005 (version 9.0.4035).
Even MSDN (URL: http://msdn.microsoft.com/en-us/library/aa260638%28v=SQL.80%29.aspx) mentions that the insert code will not work if an attempt to club insert with exec is executed on a table variable. Unfortunately, the MSDN page on top, mentions that the page applies to SQL Server 2000, which adds to the confusion.
Would someone throw some light on this? Thanks in advance.
The equivalent SQL 2008/2005 MSDN page is different::
However, table cannot be used in the
following statement:
SELECT select_list INTO table_variable
This is because the SELECT ... INTO creates the target table, and the create semantics are not compatible with variable scope semantics.
INSERT INTO #table EXEC ... is supported. You cannot specify a table-valued parameter, but that is different from a table variable.

How do I supply the FROM clause of a SELECT statement from a UDF parameter

In the application I'm working on porting to the web, we currently dynamically access different tables at runtime from run to run, based on a "template" string that is specified. I would like to move the burden of doing that back to the database now that we are moving to SQL server, so I don't have to mess with a dynamic GridView. I thought of writing a Table-valued UDF with a parameter for the table name and one for the query WHERE clause.
I entered the following for my UDF but obviously it doesn't work. Is there any way to take a varchar or string of some kind and get a table reference that can work in the FROM clause?
CREATE FUNCTION TemplateSelector
(
#template varchar(40),
#code varchar(80)
)
RETURNS TABLE
AS
RETURN
(
SELECT * FROM #template WHERE ProductionCode = #code
)
Or some other way of getting a result set similar in concept to this. Basically all records in the table indicated by the varchar #template with the matching ProductionCode of the #code.
I get the error "Must declare the table variable "#template"", so SQL server probably things I'm trying to select from a table variable.
On Edit: Yeah I don't need to do it in a function, I can run Stored Procs, I've just not written any of them before.
CREATE PROCEDURE TemplateSelector
(
#template varchar(40),
#code varchar(80)
)
AS
EXEC('SELECT * FROM ' + #template + ' WHERE ProductionCode = ' + #code)
This works, though it's not a UDF.
The only way to do this is with the exec command.
Also, you have to move it out to a stored proc instead of a function. Apparently functions can't execute dynamic sql.
The only way that this would be possible is with dynamic SQL, however, dynamic SQL is not supported by SqlServer within a function.
I'm sorry to say that I'm quite sure that it is NOT possible to do this within a function.
If you were working with stored procedures it would be possible.
Also, it should be noted that, be replacing the table name in the query, you've destroyed SQL Server's ability to cache the execution plan for the query. This pretty much reduces the advantage of using a UDF or SP to nil. You might as well just call the SQL query directly.
I have a finite number of tables that I want to be able to address, so I could writing something using IF, that tests #template for matches with a number of values and for each match runs
SELECT * FROM TEMPLATENAME WHERE ProductionCode = #code
It sounds like that is a better option
If you have numerous tables with identical structure, it usually means you haven't designed your database in a normal form. You should unify these into one table. You may need to give this table one more attribute column to distinguish the data sets.