Creating a DTS package that uses a stored procedure - stored-procedures

We're trying to make a DTS package where it'll launch a stored procedure and capture the contents in a flat file. This will have to run every night, and the new file should overwrite the existing file.
This wouldn't normally be a problem, as we just plug in the query and it runs, but this time everything was complicated enough that we chose to approach it with a stored procedure employing temporary tables. How can I go about using this in a DTS package? I tried going the normal route with the Wizard and then plugging in EXEC BlahBlah.dbo... It did not care for that:
The Statement could not be parsed. Additional information: Invalid object name '#DestinyDistHS'. (Microsoft SQL Server Native Client 10.0)
Can anyone guide me in the right direction here?
Thanks.

Is it an option to simply populate a non-temp table in your SP, call it and select from the non temp table when exporting?
This is only an issue if you have multiple simultaneous calls to the stored procedure. In this case you can't save to a single table.
If you do have multiple simultaneous calls then you might be able to:
Create a temp table to hold results
Use INSERT INTO #TempTable EXEC YourProc
SELECT FROM #TempTable
You might need to do this in a more forgiving command line tool (like SQLCMD). It's not as fussy about metadata.

Related

Is there a way to avoid the target table in informatica (powercenter)?

In informatica mapping design, there must be a target table, but in my design, I only use informatica to call store procedures, and after they were called, all work has been done, so I don't need a target table to be inserted or updated.
I used a non-exist table as the target table, and one nonsense field as the input port(cause there must be at least one input port!), then unchecked or the option(insert, update,delete) in the session configuration, so that the informatica would not generated DML SQL statements, avoiding "no table" errors.
But then informatica treat the input row as reject row and try to write it into a bad file. And cause I unchecked the insert option, the session log showed that there was an error that it couldn't be insert into the bad file!
Strangely, this error never showed in the monitor, and all session run successfully! It only appeared in informatica's meta table.
Is there a better way to avoid this problem, although it has no effect to my result? Is there a possibility to use a non-exist table and do nothing to it (include reject the input rows)?
Use a filter transformation just before the target and put filter condition 'FALSE'
No rows will go to the target
I had run into this same issue when i wanted to just execute a stored procedure and nothing else.
I solved this by creating a dummy source object that had one port and a dummy target with one port of the same datatype. In the source qualifier I added a SQL statement select 1 from dual (since it's Oracle).
I then added a filter object that was set to false. Then I connected the single port from the source/qualifier through the filter and finally to the target.
When the mapping is run, the source qualifier will return 1 row of one value, this will pass through to the filter but nothing will come out of the filter because the filter is set to false. This mapping will always be successful and valid because all ports are connected a nothing makes it to the "dummy" target thus no bad file logs or failure, etc.
Let me know if you need any clarification and I can update this answer.
No, you always need a target for the mapping to be valid. But I would rather work with a flat file target instead of a database table, you'll have much less work to do.
If you're on Linux / Unix, you can even route the file to /dev/null (use folder:/dev/, file:null) so the file is not actually written to the filesystem.
And using one dummy port is the right way. As you have said, you need at least one port, even if you don't really use it.
As odd as this may sound (Unix systems): neither source, nor target need to exist.
Source (flat file): /dev/null, column DUMMY
Target (flat file): /dev/null, column DUMMY
And you don't need to use any databases for the session to succeed, nor use any filters. It runs.

Creating temp table with PID in ESQL/C

I am using ESQL/C code to provide backend support for a UI, connecting to an Informix database. I am creating temp table inside my code. But, I guess that if multiple users use this UI at the same time then temp table might already exist in the database which can create problem. So, can someone suggest if I can create temp table with PID as suffix inside my ESQL/C code
create temp table tabname_PID (name char(10));
In shell script I generally use tabname_$$.
You can create the table with the PID embedded in it, but it isn't necessary. Any temporary table is only visible in the session that creates it, so you can use the same table name in each session (separate but concurrently executing ESQL/C program) without any fear of conflict.
If, despite the reassurances that it is unnecessary, you still want to do it, then you'll have to PREPARE and EXECUTE (or DECLARE, OPEN, FETCH, CLOSE) the statements from a string:
snprintf(sql, sizeof(sql), "CREATE TEMP TABLE tabname_%d(name CHAR(10))", (int)getpid());
EXEC SQL PREPARE s FROM :sql;
EXEC SQL EXECUTE s;
or use EXECUTE IMMEDIATE (which is the obvious winner here):
EXEC SQL EXECUTE IMMEDIATE :sql;
You will also then have to prepare all the queries; one distinct advantage of using the fixed-name temporary table is that you don't have to prepare everything that references the temp table if you don't want to (though there are often advantages to using PREPARE etc).
You don't have to use $$ in shell scripts either, for the same reason — temporary tables are private to a session.

How can I create a D-Base IV table using Delphi ADO components please?

I am working on the software for an instrument that logs batch results into single DBase 4 (*.dbf) disk files in a folder. In preparation for adding new logging analysis capability which is planned to work with multiple of these DBF files, I am changing the existing simple BDE TTable and CreateTable which reopen and create a new DBF file respectively into use of the Delphi ADO components.
Using other suggestion here on SO I have successfuly created a test application which opens an existing DBF file using the following core code using a TAdoDataSet and a TAdoConnection:
ADODataSet1.DisableControls;
try
S := ExtractFileDir( ParamStr(0) ); //set the dbf folder location here
ADOConnection1.LoginPrompt:=false;
ADOConnection1.ConnectionString:=Format('Provider=Microsoft.JET.OLEDB.4.0;Data Source=%s;Extended Properties=dBase IV;',[S]);
ADOConnection1.Connected:=True;
ADODataSet1.CommandText:='Select * from test.dbf'; //The SQL query uses the name of the dbf file
ADODataSet1.Open;
finally
AdoDataSet1.EnableControls;
end;
This works fine but before my DBF is used for the first time I will also need to creat an empty DBF file ready to add my log records. I could do this by opening an exising 'empty' DBF file each time but I was hoping that there was an SQL? way of creating my file if I have already created and defined my fields (which is easy for me). I tried this with a TAdoTable where I could created the required fields but I could not find any examples of how to get this table structure out onto disk when nothing was already there, mainly because there are so many ADO examples but almost always working on existing data tables.
Can anyone help me create a sample DFB table file with a couple of fields using ADO components please? I'm sure I can then build on that.
Many Thanks.
Use TADOCommand and execute Create Table SQL, for example something like this :
Create Table Test (TestField1 char(64), TestField2 integer)

How to call a stored procedure in IBM System i Access for Windows GUI Tool

I would like to test a DB2 stored procedure running on an AS400 system.
I have the IBM System i Access for Windows installed and can run SQL commands against the DB2 database.
My question is: What is the syntax to execute a stored procedure that takes in a parameter and returns a result as an output parameter and print the value to the screen?
Just to clarify: I am not asking how to call the proc in code. I want to execute the proc and see the results in the gui tool (which is similar to SQL Enterprise Manager).
use the keyword call and pass in the parameters.
call myStoredProc(parm1, parm2, ?);
for more details see here http://www.ibm.com/developerworks/data/library/techarticle/dm-0503melnyk/. The interesting part is Figure 5. Using the Command Editor to call an SQL procedure
What you want is possible. I have done it myself many times. Unfortunaly, I'm not at the office right now so it must be from the top of my head.
Start System i Access
Go to your iSeries icons and log on to the one where your stored procedure lives
Go to the databases icons and connect to the correct one (you've one local and probably one or more remotes)
Only then, you will see the option "run SQL script" at the bottom of your screen
Start that option and you will see a SQL editor (editor on top, viewer/messages at the bottom)
Remember that you are already connected to the correct iSeries but your JDBC request will get the *LIBL of the userprofile of your connection. Therefore you must know the schema (iseries library) of your stored procedure
Enter "call YOURSCHEMA.YOURSTOREDPROCEDURE(?,?);" and use the menu or shortcut to run that statement. Notice that - depending on your JDBC settings (see menu) - the correct syntax may be "/" instead of ".". Also, notice that you can replace the first question mark with a value.
On an additional note,
In iAccess, under every schema you will see icons for the tables, views and so on. Also an icon for stored procedures is available. You will see your SP there. Use the options to see the definition and so. This information includes detailed information about the parameters
If you want to check that on your iSeries, use the system catalog (this can be done from the SQL editor too) with "select * from qsys2.sysprocedures where procedure_name (sorry, not sure about the name of this column right now) = 'YOURSTOREDPROCEDURE';"
VERY IMPORTANT: I was never able to test the SP with the SQL editor (STRSQL) on the iSeries itself. Only the iAccess SQL editor did work correctly.
You should be able to run your SP like this:
DECLARE
usr_in YOUR_TABLE.YOUR_COLM%TYPE; --Gets the correct type by looking at column type
app_in YOUR_TABLE.YOUR_OTHER_COLM%TYPE;
BEGIN
usr_in:='some value';
app_in:='another_value';
YOUR_SP_NAME(usr_in, app_in);
END;
Or you can use EXECUTE, but it can't be dynamically prepared (not run in Java) and I think there's some other disadvantages.
EXECUTE myStoredProc(parm1, parm2, ?);

External stored procedure on IBM i

I am trying to create an external stored procedure on an IBM i (V5R4), but I'm getting an error when I try to run it.
All I want to do is call an RPG program, without passing any parameters or worrying about returning any data. Sorry, I'm not an RPG programmer or an expert on IBM i, so I could be missing something very simple.
The SQL to create the procedure:
CREATE PROCEDURE SOMELIB.SOMEPROC ( )
LANGUAGE RPGLE
NOT DETERMINISTIC
NO SQL
EXTERNAL NAME 'OTHERLIB/SOMERG'
PARAMETER STYLE GENERAL;
The error I get when executing CALL SOMELIB.SOMEPROC() is:
SQL State: 38501
Vendor Code: -443
Message: [CEE9901] Application error. RNX1216 unmonitored by BB1002RG at statement 2100000001, instruction X'0000'. Cause . . . . . : The application ended abnormally because an exception occurred and was not handled. The name of the program to which the unhandled exception is sent is SOMERG SOMERG . The program was stopped at the high-level language statement number(s) at the time the message was sent. If more than one statement number is shown, the program is an optimized ILE program. Optimization does not allow a single statement number to be determined. If *N is shown as a value, it means the real value was not available. Recovery . . . : See the low level messages previously listed to locate the cause of the exception. Correct any errors, and then try the request again.
Your procedure is calling the RPG program without the library list set. You can do one of two things:
1) Change the F-spec in the RPG program to qualify the library using the EXTFILE keyword.
2) Call a CL program from the stored procedure that adds the appropriate library to the library list making sure to allow for the fact that the library may already be there from a prior call. Then have the CL program call the RPG program.
(a little bit more rude solution) Identify the user that starts the Stored Procedure. Change the jobdescription of that user to have the correct library list.
But in my experience is the CL program the most pragmatic solution too.
Assuming the file is in the same library as the program, add EXTFILE(variablename) and USROPN to the F-spec. Take the library name from the PSDS and construct the variablename value before you OPEN the file.
If the file and program are in different libraries, you might create a data area in the program library to hold the name of the data library. Retrieve the data area (using the PSDS) instead of using the PSDS (for the file library). If program and file aren't kept together, it can be a good idea to keep the data library name in an external object that can be changed rather than recompiling.
(Actually, I've rarely used data areas in the past ten years or so. Instead I create a user index. Each entry in the *USRIDX replaces a data area. The entries are keyed by a value that used to be a data area name. One object replaces many others and one procedure can manage all entries. One object to own and authorize reduces some system overhead.)
A suggestion to get rid of this trouble: make the user profile JOBD contains all libraries needed by the stored procedure.

Resources