I have created a Web Service to send in a bunch of information to a PL/SQL procedure, however one of them is a array. What type do I use for this? I also want to put that array into a cursor after it comes in.
I don't have any experience with PL/SQL, so sorry if this doesn't apply. In MS SQL 2000/2005, there isn't a way to pass arrays into a procedure; I'm assuming PL/SQL has a similar limitation. The workaround I've used in the past is to pass in a delimited string (usually pipe delimited because commas were present in the data), and then have a function that can take a delimited string and break it up into a table result with one row per value. Then inside your procedure, you just call your split function passing it the delimited string and you have a table result that you can do whatever you want with (cursor over, join to other tables, etc).
EDIT: Just did a google for "PL/SQL table parameter" and had a few hits; Might be worth investigating to see if any of those results can help you.
This link might be of use. Or you can do what the other poster said and basically serialize your data into a string, pass it, and then unserialize it on the other end.
Related
Right now, I run a stored procedure whose output feeds a "Create CSV Table" Data Operations component. This component, not surprisingly, outputs a comma-delimited list of fields, which is not supported by our remote system. The fields need to be tab-delimited. One would think that the Data Operations component would have a tab (or other character-delimited option). But no, only commas are available, and no other Data Operations component outputs a tab-delimited table.
Using any mechanism for which we'd have to write code is completely the last option, as there's no need for code to use CSV. Also, any mechanism which requires paying for 3rd party components is categorically out, as is using any solution which is in preview mode.
The only option we've thought of is to revamp the stored procedure which outputs a single "column" containing the tab-delimited columns, and then output to a file - ostensibly, a comma-delimited file, but one without commas embedded inside (which is allowed for my system) so that the single column isn't itself enquoted.
Otherwise, I guess Function Apps is the solution. Anyone with ideas?
The easiest way is to use string function and replace comma with other delimiter. If you could accept this way, after creating the csv table I initiate a string variable with this input replace(body('Create_CSV_table_2'),',',' ').
And this is the result.
And if you don't want this way, yes you have to solve it with code and the Function is a choice.
Is it possible in SQL Server to define a String constant? I am rewriting some queries to use stored procedures and each has the same long string as part of an IN statement [a], [b], [c] etc.
It isn't expected to change, but could at some point in future. It is also a very long string (a few hundred characters) so if there is a way to define a global constant for this that would be much easier to work with.
If this is possible I would also be interested to know if it works in this scenario. I had tried to pass this String as a parameter, so I could control it from a single point within my application but the Stored Procedure didn't like it.
You can create a table with a single column and row and disallow writes on it.
Use that as you global string constant (or additional constants, if you wish).
You are asking for one thing (a string constant in MS SQL), but appear to maybe need something else. The reason I say this is because you have given a few hints at your ultimate objective, which appears to be using the same IN clause in multiple stored procedures.
The biggest clue is in the last sentence:
I had tried to pass this String as a
parameter, so I could control it from
a single point within my application
but the Stored Procedure didn't like
it.
Without details of your SQL scripts, I am going to attempt to use some psychic debugging techniques to see if I can get you to what I believe is your actual goal, and not necessarily your stated goal.
Given your Stored Procedure "didn't like that" when you tried to pass in a string as a parameter, I am guessing the composition of the string was simply a delimited list of values, something like "10293, 105968, 501940" or "Juice, Milk, Donuts" (pay no attention to the actual list values - the important part is the delimited list itself). And your SQL may have looked something like this (again, ignore the specific names and focus on the general concept):
SELECT Column1, Column2, Column3
FROM UnknownTable
WHERE Column1 IN (#parameterString);
If this approximately describes the path you tried to take, then you will need to reconsider your approach. Using a regular T-SQL statement, you will not be able to pass a string of parameter values to an IN clause - it just doesn't know what to do with them.
There are alternatives, however:
Dynamic SQL - you can build up the
whole SQL statement, parameters and
all, then execute that in the SQL
database. This probably is not what
you are trying to achieve, since you
are moving script to stored
procedures. But it is listed here
for completeness.
Table of values -
you can create a single-column table
that holds the specific values you
are interested in. Then your Stored
Procedure can simply use the column
from this table for the IN clause).
This way, there is no Dynamic SQL
required. Since you indicate that
the values are not likely to change,
you may just need to populate the
table once, and use it wherever
appropriate.
String Parsing to
derive the list of values - You can
pass the list of values as a string,
then implement code to parse the
list into a table structure on the
fly. An alternative form of this
technique is to pass an XML
structure containing the values, and
use MS SQL Server's XML
functionality to derive the table.
Define a table-value function that
returns the values to use - I have
not tried this one, so I may be
missing something, but you should be
able to define the values in a
table-value function (possibly using
a bunch of UNION statements or
something), and call that function
in the IN clause. Again - this is an
untested suggestion and would need
to be worked through to determine
it's feasibility.
I hope that helps (assuming I have guessed your underlying quandary).
For future reference, it would be extremely helpful if you could include SQL script showing
your table structure and stored procedure logic so we can see what you have actually attempted. This will considerably improve the effectiveness of the answers you receive. Thanks.
P.S. The link for String Parsing actually includes a large variety of techniques for passing arrays (i.e. lists) of information to Stored Procedures - it is a very good resource for this kind of thing.
In addition to string-constants tables as Oded suggests, I have used scalar functions to encapsulate some constants. That would be better for fewer constants, of course, but their use is simple.
Perhaps a combination - string constants table with a function that takes a key and returns the string. You could even use that for localization by having the function take a 'region' and combine that with a key to return a different string!
I need to create a stored procedure which receives a parameter (named #codes).
This is a string which contains a list of codes separated by a semicolumn.
I'd need to look inside a table and return all rows that have a code (which is in the column EANcodes) which was passed in the #codes parameter.
Can anyone help me get started. My knowledge of stored procedures is very limited.
Thanks in advance.
Ideally, I'd prefer to see the parameter passed in another way, either using a table-value parameter (assuming SQL 2008) or XML which can be easily shredded into a table.
Alternatively, use a SQL split function (one example is here) to parse the string into a temp table, then join against that table in your select query.
Stored Procedures aren't really meant to handle a list of strings as a paramter. You'd be better off splitting it up in your App code and then calling the stored procedure many times with each one as a parameter.
However, if you feel the need to do it this way. You could loop through the string, and use CHARINDEX to find the next index of a semicolon and then use SUBSTRING to get the next code. Then you could use a CTE for the matching rows at each iteration and when the loop is done, simply return the CTE. This is pretty hacky, but I can't think of any other way to do this.
(Those are the T-SQL string functions)
For info on the string manipulation functions (in T-SQL): http://msdn.microsoft.com/en-us/library/ms186323.aspx
And here are similar functions in MySQL: http://dev.mysql.com/doc/refman/5.1/en/string-functions.html
I have a SQL Server 2008 database. This database has a stored procedure that will update several records. The ids of these records are stored in a parameter that is passed in via a comma-delimited string. The property values associated with each of these ids are passed in via two other comma-delimited strings. It is assumed that the length (in terms of tokens) and the orders of the values are correct. For instance, the three strings may look like this:
Param1='1,2,3,4,5'
Param2='Bill,Jill,Phil,Will,Jack'
Param3='Smith,Li,Wong,Jos,Dee'
My challenge is, I'm not sure what the best way to actually go about parsing these three CSVs and updating the corresponding records are. I have access to a procedure named ConvertCSVtoTable, which converts a CSV to a temp table of records. So Param1 would return
1
2
3
4
5
after the procedure was called. I thought about a cursor, but then it seems to get really messy.
Can someone tell me/show me, what the best way to address this problem is?
I'd give some thought to reworking the inputs to your procedure. Since you're running SQL 2008, my first choice would be to use a table-valued parameter. My second choice would be to pass the parameters as XML. Your current method, as you already know, is a real headache and is more error prone.
You can use bulk load to insert values to tmp table after that PIVOT them and insert to proper one.
I have a table in my MS SQL database where it has some incomplete data in a field. This field in question is a varchar field and has about 1000 characters in the field. This string consists of segmentations of words in the format of a forward slash followed by the segment and then ends with a forward slash (i.e. /p/). Each of these segments would be separated by a space. The problem is that certain of these segmentations do not have the last forward slash (i.e. /p). I need to write a T-SQL script that would correct this problem.
I know I will need to use an update statement to do that. I got the where clause too. But the problem that I have is what am I setting it to equal to. Since the string has about 1000 characters, I don't want to type the actual string and just correct the problematic segmentation. My question is, is there a "RegEx replace function" that would only change problematic segmentations and leave the rest of the string alone?
Your help will be greatly appreciated.
Thanks in advance,
Monte
SQL doesn't support RegEx within it. You could write a SQL CLR function then pipe the data through it and if there's a problem with the data correct it then return the corrected version to SQL.
UPDATE YourTable
Set YourColumn = dbo.YourClrProc(YourColumn)
If you have Windows Scripting Host installed (most machines do), then you can use this method to call into the VBScript.RegExp object from T-SQL.
There is REPLACE, but is nothing close to RegEx.
If this is a one time operation then you can consider exporting the table, use a tool you're familiar with like sed or grep and then import the modified data back. It will probably be faster and more correct than trying to do this in T-SQL.
On the other hand if is a planned maintenance operation you'll need to repeat often as a way to maintain the data, then I concur with mrdenny, a CLR function is probably the best choice.