My Stored procedure takes one parameter #IDs and it has values in it like '1,2,3'. I want to get rid of these single quotes. How can I do it? Like I want just 1,2,3 and NOT '1,2,3'. How do I modify this parameter value inside my SP?
you can do this:
#IDs = REPLACE(#IDs, '''', '');
If your parameter is VARCHAR, NVARCHAR or something like string :)
You could use a table varaible instead, read in BOoks online for how to do that.
Related
I want to pass a parameter to sp with N prefix to solve an issue with foreign languages characters recognized as ???, I can't put N#test, directly, tried different ways without luck.
I have aspx.cs code file where I call to an sp, I want to do something like the following:
DECLARE #test NVARCHAR = 'N"★ "'
create table test (abc nvarchar)
insert into test values (#test)
select * from test
the code above is just an example, I will pass value to the parameter from .NET, How can I do it?
You don't need N prefix. You can specify parameter type as SqlDbType.NVarChar along with size. .Net will take care of preserving text encoding.
var foo = new SqlParameter("#test ", SqlDbType.NVarChar, 30)
N prefix means that your string is in UNICODE.
When you declare your variable as NVARCHAR it is already UNICODE.
So you don't need this N lineral at the begin of your variable.
I am building a website in ASP.NET 2.0, some description of the page I am working about:
ListView displaying a table (of posts) from my access db, and a ListBox with Multiple select mode used to filter rows (by forum name, value=forumId).
I am converting the ListBox selected values into a List, then running the following query.
Parameter:
OleDbParameter("#Q",list.ToString());
Procedure:
SELECT * FROM sp_feedbacks WHERE forumId IN ([#Q])
The problem is, well, it doesn't work. Even when I run it from MSACCESS 2007 with the string 1,4, "1","4" or "1,4" I get zero results. The query works when only one forum is selected. (In (1) for instance).
SOLUTION?
So I guess I could use WHERE with many OR's but I would really like to avoid this option.
Another solution is to convert the DataTable into list then filter it using LINQ, which seems very messy option.
Thanks in advance,
BBLN.
I see 2 problems here:
1) list.ToString() doesn't do what you expect. Try this:
List<int> foo = new List<int>();
foo.Add(1);
foo.Add(4);
string x = foo.ToString();
The value of "x" will be "System.Collections.Generic.List`1[System.Int32]" not "1,4"
To create a comma separated list, use string.Join().
2) OleDbParameter does not understand arrays or lists. You have to do something else. Let me explain:
Suppose that you successfully use string.Join() to create the parameter. The resulting SQL will be:
SELECT * FROM sp_feedbacks WHERE forumId IN ('1,4')
The OLEDB provider knows that strings must have quotation marks around them. This is to protect you from SQL injection attacks. But you didn't want to pass a string: you wanted to pass either an array, or a literal unchanged value to go into the SQL.
You aren't the first to ask this question, but I'm afraid OLEDB doesn't have a great solution. If it were me, I would discard OLEDB entirely and use dynamic SQL. However, a Google search for "parameterized SQL array" resulted in some very good solutions here on Stack Overflow:
WHERE IN (array of IDs)
Passing an array of parameters to a stored procedure
Good Luck! Post which approach you go with!
When you have:
col in ('1,4')
This tests that col is equal to the string '1,4'. It is not testing for the values individually.
One way to solve this is using like:
where ','&#Q&',' like '*,'&col&',*'
The idea is to add delimiters to each string. So, a value of "1" becomes ",1,"in the column. A value of "1,4" for #Q becomes ",1,4,". Now when you do the comparison, there is no danger that "1" will match "10".
Note (for those who do not know). The wildcard for like is * rather than the SQL standard %. However, this might differ depending on how you are connecting, so use the appropriate wildcard.
Passing such a condition to a query has always been a problem. To a stored procedure it is worse because you can't even adjust the query to suit. 2 options currently:
use a table valued parameter and pass in multiple values that way (a bit of a nuisance to be honest)
write a "split" multi-value function as either a UDF or via SQL/CLR and call that from the query
For the record, "dapper" makes this easy for raw commands (not sprocs) via:
int[] ids = ...
var list = conn.Query<Foo>(
"select * from Foo where Id in #ids",
new { ids } ).ToList();
It figures out how to turn that into parameters etc for you.
Just in case anyone is looking for an SQL Server Solution:
CREATE FUNCTION [dbo].[SplitString]
(
#Input NVARCHAR(MAX),
#Character CHAR(1)
)
RETURNS #Output TABLE (
Item NVARCHAR(1000)
)
AS BEGIN
DECLARE #StartIndex INT, #EndIndex INT
SET #StartIndex = 1
IF SUBSTRING(#Input, LEN(#Input) - 1, LEN(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE CHARINDEX(#Character, #Input) > 0
BEGIN
SET #EndIndex = CHARINDEX(#Character, #Input)
INSERT INTO #Output(Item)
SELECT SUBSTRING(#Input, #StartIndex, #EndIndex - 1)
SET #Input = SUBSTRING(#Input, #EndIndex + 1, LEN(#Input))
END
RETURN
END
Giving an array of strings, I will convert it to a comma separated List of strings using the following code
var result = string.Join(",", arr);
Then I could pass the parameter as follows
Command.Parameters.AddWithValue("#Parameter", result);
The In Stored Procedure Definition, I would use the parameter from above as follows
select * from [dbo].[WhateverTable] where [WhateverColumn] in (dbo.splitString(#Parameter, ','))
I have a table userdata which has these columns:
userId
userName
userEmail
userContact
userDob
userAdd
userImage
userPass
I am using a stored procedure to select data from this table.
Now I want to update this table with a stored procedure. I am able to update this table with stored procedure but my requirement is in profile.aspx I allow user to update all columns with stored procedure. But in other forms I want user to update a few columns only, for example on setting.aspx page I allow user to update only userPass column.
So I have to make another stored procedure. And I have many tables like this. And I wondered how many stored procedure I have to create to update many tables with different columns.
Can anyone suggest a short way so that I can do this with only one stored procedure per table to update whole table or individual columns, too or any c# code to shorten this?
Thanks in advance
You can use the ISNULL function in MS SQL Server, which is explained by below statement from MSDN.
Replaces NULL with the specified replacement value.
You can write one stored procedure, which updates all the fields that you want to update in various operations. Call the same procedure from all pages. Then from a page only pass relevant parameters for that page & for the remaining parameters (that are not relevant to that page) pass null.
Your stored procedure should be like this
UPDATE dbo.userTable SET
userName = ISNull(#userName, userName),
userEmail= ISNull(#userEmail, userEmail),
-- list of all your table fields goes here
WHERE userID = #userID
What this will do is, if you pass the parameter; it will update value for that field; and if you pass null for any field it will update that field with its existing value. So that field will not be affected in the update operation.
You can have single stored proc with multiple if.. else.. condition to control updation of each single field. Then you can pass them as parameter to control which field to update.
I think you can do like this:
At the front page, you should set the fields not editable that you didn't want to update, but pass the values as parameters to the store-procedure. In store-procedure, you campare the old value of these fields to the correspondding parameters, If not equal, update it, otherwise, do nothing with these fields.
you could use something like this:
UPDATE tbl t
SET t.userName = CASE WHEN #userName IS NULL THEN t.userName ELSE #userName END
, t.userEmail = CASE WHEN #userEmail IS NULL THEN t.userEmail ELSE #userEmail END
, ...
WHERE t.userName = CASE WHEN #WHERE_userName IS NULL THEN t.userName ELSE #WHERE_userName END
AND ...
So if you do not want to update specific field just pass DBNull.Value from the code to the procedure call for that parameter.
Keep in mind that this will work only if you do not intend to update a field with NULL value.
If you need nulls you could then rewrite a little bit the code to make it work with nulls. If you need further help, just put a comment.
Get your all data in Datatable for which you need to update.
use datatable.WriteXML method and get in Stream object all the string use XmlWriteMode.IgnoreSchema to get only data.
DataTable dt = new DataTable();
dt.WriteXml(stream object ,XmlWriteMode.IgnoreSchema)
Now create procedure which accept Varchar(max) parameter and pass Stream object to the procedure.
After that you are able to use Openxml or get all this thing in XML variable in Sqlserver
get all data in #tablevariable or in #temp table.
Openxml in sqlserver
or
For Xml for XMl variable
then you will get every thing in one table use that table to update your
database table base on your primary key ID
like....
SQl qquery is like below
Update "Database Table Name"
set .........
from "GetDatafromc#table"
I have written the following stored procedure in SQL Server 2008 :
ALTER Procedure [dbo].[usp_TodayNumberOfRegisteration]
(
#TodayShamsiDate nvarchar
)
AS
Select COUNT(csci.Id) as cc1 FROM dbo.Complex_Service_Cart_Items csci INNER JOIN dbo.Complex_Service_Cart csc
ON csci.Id_Complex_Service_Cart=csc.Id
WHERE (csci.Id_Complex_Service='2cca1a67-34f4-4837-bebe-f3ba4c72b98d' or csci.Id_Complex_Service='8430cad2-dbb1-4425-bb8b-a7e158f688c4')
and csc.TFIsPaymentComplete=1
and csc.TFDateBackFromBankp= RTRIM( #TodayShamsiDate)
And I am calling it from C# codebehind via EF4 this way :
string shamsiDate = Date.getShamsiDate();
returnValue = Convert.ToString(db.getTodayNumberOfRegisteration(shamsiDate).First().Value);
where getTodayNumberOfRegisteration is a function I added to my edmx model .
Now here is the issue : when I execute the stored procedure in SQL Server and instead of
and csc.TFDateBackFromBankp= RTRIM( #TodayShamsiDate)
I set something like :
and csc.TFDateBackFromBankp= RTRIM( '1391/12/05')
This stored procedure returns a value of 6
But when I pass the parameter from C# codebehind and I get the return value '0'
Any help would be appreciated.
I normally do it like this: in the Add Function Import dialog, select your stored procedure and define that it returns a Collection Of Scalars: Int32:
Then in your code, call it like this:
int value = db.getTodayNumberOfRegisteration(shamsiDate).First().Value;
This usually works just fine for me.
If you don't define it as returns a collection of: Int32, it seems that the value you're getting back is really the return value from the stored procedure call, e.g. the number of rows that were affected by the stored procedure execution (0 or -1 for a SELECT, since you didn't actually insert, update or delete any rows):
I found the issue :
I had set the parameter this way :
#TodayShamsiDate nvarchar
and I should have specified the length of nvarchar
#TodayShamsiDate nvarchar(10)
I did It and the problem is solved !
In a SQL stored proc i'm inserting a row and hoping to return the IDENTITY INT for the new row, then get it in my C# code.
ALTER PROCEDURE the_proc #val_2 VARCHAR(10), #val_3 VARCHAR(10)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO the_table (field_2, field_3)
OUTPUT INSERTED.field_1
VALUES (#val_2, #val_3)
END
In C# i'm using LINQ but am fuzzy on how to retrieve that OUTPUT value. I tried including it as an OUTPUT parameter in the SQL proc declaration, but couldn't get that working either (exceptions complaining about it not being supplied in the call). The closest i've gotten is in walking into the Db.designer.cs code, where IExecuteResult result ReturnValue contains 0 (not correct) but inspecting the contained Results View (result.ReturnValue Results View) DOES have the outputed value.
key = (int)(db.TheProc(val2,val3).ReturnValue);
key is coming back as 0. I want the IDENTITY INT value from the INSERT.
OUTPUT INSERTED.*
is basically the same thing as doing a select. So this isn't going to show up as an output parameter but rather come back as a result set.
BTW, the ReturnValue should actually be zero which is what you are seeing in this case.
You'll need to change your linq statement so that you capture that result set.
Try this instead (assuming SQL Server) :
ALTER PROCEDURE the_proc
#val_2 VARCHAR(10),
#val_3 VARCHAR(10),
#newKey int OUTPUT
AS
BEGIN
SET NOCOUNT ON
INSERT INTO the_table (field_2, field_3) VALUES (#val_2, #val_3)
SET #newKey = SCOPE_IDENTITY()
END
Once you define your the_proc stored procedure to your LINQ to SQL dbml you can do this:
int? newKey = null;
dataContext.the_proc("val1", "val2", ref newKey);
// newKey.Value now contains your new IDENTITY value
Chris Lively nudged me in the right direction, which is to say re-examining the C# Linq code. The following pulls Field_1 out of the results. Maybe it's a weird way to get there and not the normal idiom, so if anyone has suggestions for something more "correct" please add a comment or answer.
var o = from res in db.MyProc( Val1, Val2 )
select res.Field_1;
int key = o.ToArray()[0];
Thanks.