I am having a great deal of trouble porting some stored procedures to regular MySQL statements.
We have stuff like this example
http://dev.mysql.com/doc/refman/5.0/en/stored-programs-defining.html
BEGIN
SET #x = 0;
REPEAT SET #x = #x + 1; UNTIL #x > p1 END REPEAT;
END
Where many statements are executed. Several If statements and variable declarations, the whole 9 yards. But for some reason I can't just copy and paste the logic of the stored procedure into MySQL's query browser and execute it nor will it execute in a query execution via a C# program
I tried porting these queries via parameterized queries in C# but I still get a "check the manual error" every time =O
I really need help i can't find an answer anywhere on the internet. Am I completely screwed trying to get sequential execution without stored procedures?
Is the only way to do this to port the logic to the actual program? (I really don't want to do this)
Edit: I have reading comprehension issues. This link says that the looping constructs only work within stored programs, so you are out of luck I think.
Related
Hi and thanks in advance. I'm trying to see if there's a way to avoid learning C (which I don't know at all) to turn userdata into a Lua table.
I'm using an application which lets users write addons using Lua scripts. These addons can query the application's underlying data. However the query results are returned as userdata and I need them to be available back in the script.
I haven't been able to find anything in the applications documentation about working with returned datasets. The only description given is that the operation I'm running:
Executes the currently assigned query string and uses the results to construct either a DataSet object if multiple result sets are returned or a DataTable if one or no result sets are returned.
In my case I'll be getting multiple result sets, I'm referring to it as userdata because that's what I get when I call type() on the query result.
I've looked at the Lua documentation which seems like it could be useful but lacking any familiarity with C I have no idea what I'm looking at. The metatable tells me I have access to the __index, __newindex, __tostring, and __gc metamethods. Calling tostring gives me a seven-digit integer which is (I think) completely unrelated to my data. It's possible I'm not even getting the data I want back at all, but I can't figure a way to check that. Online resources either say this can't be done or provide solutions in C which are probably clever, clean, and awesome but I don't understand them.
So I'm looking for some more definitive guidance on whether I can/should do this, if there's a way to do this without C (or just by blindly copying someone else's code), or -- if I need to use C for this -- if we're talking about the 90 minute or the 7 hour Lynda Introduction to C course to get where I need to be?
(and apologies if I've inadvertently violated any community norms with this question...it's my first time posting)
I am responsible for converting an old UNIX based COBOL batch application that was developed by a consultant back in the 1990s to a Windows environment but still in COBOL using Microfocus (Eclipse, etc).
This is a pretty straight-forward task except for one little glitch.
The old application never did any explicit file handling within the COBOL. That is there are no FDs, OPENs, READs, WRITEs or CLOSE commands in the COBOL programs. Instead they wrote a C program that would do one of those different functions based on parameters passed to it (including, but not limited to file name, rec length, and the function desired.)
I would like to rewrite that subroutine in COBOL, which would require very little modifications to the COBOL main programs being converted. That is, it would still call that subroutine, but it would now be in COBOL instead of C.
But the challenge is how to write that subroutine so that it is able to act on most any file. I would think I have to go the route of variable length records because they could literally be any length up to to-be-determined maximum size, but seems like it would be vulnerable to error (as it tries to open different types of files).
Does anybody have any experience on this or ideas on a task like this? If not,l I may have to go the blunt force route of replacing each call statement to that subroutine with the specific COBOL command (Open, Read, etc) that needs to be performed and obviously FD and SELECT for every file would need to be added to the main program.
Thanks in advance.
You might be able to
CALL "subprogram" USING fd-name
where fd-name is
FD fd-name.
...
So, yes? maybe?, you might be able to pull off a subprogram that can take generic COBOL files. But, then you get into matching record layouts and other fun things, so, be wary. This might not work COBOL to COBOL, but it does work COBOL to C and back, as you end up passing a reference to the file control block.
You'll likely be better off looking into stock system libraries. Things like CBL_OPEN_FILE and CBL_READ_FILE if they are available. This will give you a much closer match to streaming IO that will be assumed in the current C subprogram.
Or, as Bill is suggesting in the comments, try and figure out why C was used and if you don't want the foreign functions, just dig in and write new COBOL procedures, as that will likely read better in the end.
I see several stored procedures in this application I am now responsible for, some of which use this syntax for cursors:
DECLARE cursor1 CURSOR WITH RETURN FOR
...and others that use this syntax for cursors:
DECLARE cursor1 CURSOR FOR
All of these stored procedures are used by Crystal Reports 11.
Please explain to me, what is the difference between these two? They both return rows to Crystal Reports successfully. I am trying to optimize this one stored procedure and I wasn't sure what this clause even does. Thanks for your help.
Did you look in the manual?
Given that you're returning results to an external client, the WITH RETURN TO CLIENT would be a better choice.
The web seems a bit short on working examples for something that should be quite common. A plain Jane example of "Get me some records". This is my first ever Stored proc and all I want is to see some records. Why is that so flipping hard? ;-) I figure that if I can get one example that works, I can tune it from there into something I can really use. This is taken from another example I found on the web. Doesn't compile because CURSOR declaration is a syntax error of some sort.
CREATE PROCEDURE "SCHEMA"."GETRESULTSET (
IN "p1" VARCHAR(30))
DYNAMIC RESULT SETS 1
BEGIN
DECLARE CURSOR cur1 WITH RETURN ONLY TO CLIENT FOR
SELECT partitioninfo FROM SCHEMA.SessionInfo where username = p1;
OPEN cur1;
END;
Anyway, sure could use a clue. I saw an example where the CURSOR was declared separately from the SQL but then there wasn't an example that showed how to get the variable into the SQL when it was declared as a VARCHAR. The example I am working off of was pretty old but it's the best I could find.
A Teradata MACRO would be a better solution for what you have described.
REPLACE MACRO [MyDB].GetResultSet(p1 VARCHAR(30)) AS (
SELECT "Partition"
FROM DBC.SessionInfo
WHERE UserName = :p1;
);
EXEC MyDB.GetResultSet
While a stored procedure could be used to accomplish the task cursor based logic used in other popular database systems (Oracle, SQL Server, etc.) can lead to bad programming habits in Teradata. Generally, processing large cursors in Teradata degrades performance. Many things that you have have used cursor for in other DBMS' are better served to be done with SET based logic where possible.
That being said cursors can be used successfully in Teradata to perform certain tasks that require conditional logic or dynamic SQL processing. I hope this helps and if you have a more concrete example you need help with I'd be happy to offer some suggestions.
Edit:
This DDL for your procedure works against Teradata 13.10:
CREATE PROCEDURE "SCHEMA"."GETRESULTSET" (
IN "p1" VARCHAR(30))
DYNAMIC RESULT SETS 1
BEGIN
DECLARE cur1 CURSOR WITH RETURN ONLY TO CLIENT FOR
SELECT "Partition" FROM "SCHEMA".SessionInfo where username = p1;
OPEN cur1;
END;
The cursor name has to proceed the CURSOR key word. PartitionInfo is not a valid column on DBC.SessionInfo. Not sure if "Schema" gets replaced by MyBatis or not, so you may have to tweak the SELECT statement.
I'm working on some legacy code in which there are a lot of WriteLn(F, '...') commands scattered pretty much all over the place. There is some useful information in these commands (what information variables contain, etc), so I'd prefer not to delete it or comment it out, but I want to stop the program from writing the file.
Is there any way that I can assign the F variable so that anything written to it is ignored? We use the console output, so that's not an option.
Going back a long long time to the good old days of DOS - If you assign 'f' to the device 'nul', then there should be no output.
assign (f, 'nul')
I don't know whether this still works in Windows.
Edit:
You could also assign 'f' to a file - assignfile (f, 'c:\1.txt') - for example.
Opening the null device and letting output go there would probably work. Under DOS, the performance of the NUL device was astonishingly bad IIRC (from what I understand, it wasn't buffered, so the system had to look up NUL in the device table when processing each byte) but I would not be at all surprised if it's improved under newer systems. In any case, that's probably the easiest thing you can do unless you really need to maximize performance. If performance is critical, it might in theory be possible to override the WriteLn function so it does nothing for certain files, but unfortunately I believe it allows syntax forms that were not permissible for any user-defined functions.
Otherwise, I would suggest doing a regular-expression find/replace to comment out the WriteLn statements in a fashion that can be mechanically restored.