How to save byte[] using a procedure? - sql-server

This stored procedure does not save the data, it seems to be a problem with the VARBINARY. I am passing a byte[] to it, but then it doesn't work. If I send this parameter as NULL it works.
I'm calling the procedure with the following code:
public Community AddCommunity(string name, string description, byte[] picture, User owner, int? venue, int communityID)
{
using (var database = new Database())
{
return database.Scope.GetSqlQuery<Community>("QP_AddCommunity ?, ?, ?, ?, ?, ?", "VARCHAR Name, VARCHAR Description, VARBINARY Picture, INTEGER Owner, INTEGER Venue, INTEGER ID").GetResult(name, description, picture, owner.ID, venue, communityID);
}
}
The procedure is the following:
CREATE PROCEDURE [dbo].[QP_AddCommunity]
#Name VARCHAR(120),
#Description VARCHAR(MAX),
#Picture VARBINARY(MAX),
#Owner INTEGER,
#Venue INTEGER,
#ID INTEGER
AS
BEGIN
SET NOCOUNT ON;
IF(SELECT COUNT(*) FROM QT_Community WHERE ID = #ID) = 0
INSERT INTO QT_Community(Name, [Description], Picture, [Owner], Venue) VALUES(#Name, #Description, #Picture, #Owner, #Venue);
ELSE
UPDATE QT_Community SET Name = #Name, [Description] = #Description, Picture = #Picture, [Owner] = #Owner, Venue = #Venue WHERE ID = #ID;
SELECT * FROM QT_Community WHERE ID = ##IDENTITY;
END
What's wrong with this code? Isn't VARBINARY a byte[] ?
This code works when executing on SQL Server Management Studio.
DECLARE #X varbinary(20)
Set #X = CAST('Testing' As varbinary(20))
EXECUTE [QP_AddCommunity] 'aaaaa', 'descricao', #X, 216, NULL, 0;
But when calling from the GetSqlQuery method with something on the byte[] the transaction says it's not active and not dirty. BUT if the byte[] is null it works as it should.

i found that it is impossible as this answer shows
Hello gaurav, currently our
GetSqlQuery method cannot operate
properly with parameters of type
LongVarBinary or VarBinary, thus
making it impossible for the stored
procedure to work as expected. We are
aware of this problem and we are
working on fixing it. As a work around
you should try and use Linq to achieve
your goal. Greetings, Petar the
Telerik team

Accordingly to this table it seems either BLOB, BINARY, VARBINARY would be valid types for [] of primitive type.
You could try to ask on their forums, maybe someone will be able to help you.

Try using the .WRITE method. On your INSERT, insert 0x for Picture, then update independently.
UPDATE QT_Community
SET Picture.Write (#Picture, 0, DATALENGTH(Picture))
WHERE ID = #ID

Example (Ado.Net):
byte[] ba = UlongsToBytes(ul);
try
{
string source = #"packet size=4096;integrated security=SSPI;data source=MyPC\MyNamedInstance;persist security info=False;initial catalog=Sandbox";
SqlConnection conn = new SqlConnection(source);
conn.Open();
SqlCommand a = new SqlCommand("INSERT BigintsTarget(bi) SELECT * FROM dbo.ParseImageIntoBIGINTs(#BIGINTs)", conn);
a.CommandType = System.Data.CommandType.Text;
a.Parameters.Add(new SqlParameter("#BIGINTs", System.Data.SqlDbType.Image,2147483647));
for(int q=0; q<10; q++)
{
a.Parameters[0].Value = ba;
int res = a.ExecuteNonQuery();
}
d2 = DateTime.Now;
SqlCommand b = new SqlCommand("INSERT BigintsTarget1(bi) SELECT * FROM dbo.ParseVarcharMAXIntoBIGINTs(#BIGINTs)", conn);
b.CommandType = System.Data.CommandType.Text;
b.Parameters.Add(new SqlParameter("#BIGINTs", System.Data.SqlDbType.VarChar,2147483647));
for(int q=0; q<10; q++)
{
b.Parameters[0].Value = sss;
int res = b.ExecuteNonQuery();
}
//b.ExecuteNonQuery();
conn.Close();
}
catch(Exception ex)
{
string s = ex.Message;
int t=0;
t++;
}
}

Related

System.Data.SqlClient.SqlException: 'Conversion failed when converting the varchar value 'gcobani' to data type int.'

I am running an exception, the conversion seem to fail when i try to create new user to the database. This hits on my Repository on this method below, meanwhile on my store procedure it returns an integer; The question would then be, how could I solve this issue? Please advice and help me to fix this better.
C# code:
public string GetUserName_By_UserID(string UserId)
{
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyString"].ToString()))
{
var para = new DynamicParameters();
para.Add("#UserId", UserId);
return con.Query<string>("Usp_UserNamebyUserID", para, null, true, 0, CommandType.StoredProcedure).SingleOrDefault();
}
}
Stored procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[Usp_UserNamebyUserID]
#UserId varchar(200)
AS
BEGIN
SELECT UserName
FROM Users
WHERE Id = #UserId
END
NB: my UserId I checked now on my table name "Users" I defined it as an Int, maybe this is the reason.
Just try with below SP:
CREATE proc [dbo].[Usp_UserNamebyUserID]
#UserId int
as
begin
select UserName FROM Users where Id =#UserId
end
You have to change your c# code like:
public string GetUserName_By_UserID(Int UserId)
{
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyString"].ToString())) {
var para = new DynamicParameters();
para.Add("#UserId", UserId);
return con.Query<string>("Usp_UserNamebyUserID", para, null, true, 0, CommandType.StoredProcedure).SingleOrDefault();
}
}

ADO.NET - Trouble Getting Output Parameter

My DBA created the following Stored Proc which he insists works fine when called in SQL Server:
CREATE procedure [dbo].[GetParentID]
#SSHIP_AppID as varchar(50),
#ParentID as varchar(150) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT #ParentID = a.iBuild_GUID
FROM dbo.XRef_iBuild_SSHIP as a
WHERE a.SSHIP_appId = #SSHIP_AppID
AND a.SSHIP_appId <> ''
END
I have created the following ADO.NET Wrapper but I am having trouble getting the output parameter. I keep getting back "OUTPUT" as its value:
private string GetParentId(string appId)
{
var connection = new SqlConnection();
string parentId = String.Empty;
try
{
connection.ConnectionString = "...)
var command = new SqlCommand("GetParentId", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#SSHIP_AppID", appId));
command.Parameters.Add(new SqlParameter("#ParentID", ParameterDirection.Output));
connection.Open();
command.ExecuteNonQuery();
parentId = (command.Parameters["#ParentId"].Value).ToString();
}
catch (Exception ex)
{
LogError(appId, ex.ToString(), "Interface12 - Cannot get ParentId", null, 0);
}
finally
{
connection.Close();
}
return parentId;
}
}
What am I doing wrong?
In new SqlParameter("#ParentID", ParameterDirection.Output) the 2nd argument is treated as the object value argument and apparently converted to a string.
(This implicit conversion is, in my opinion, a design flaw in ADO.NET. It should throw an exception for any unknown input type.).
Choose a better overload.

Error when inserting a value containing an apostrophe

I'am very new with text datatype in SQL Server 2008
I created table:
CREATE TABLE sample(id int identity,name varchar(20),Yell_Your_self text)
but I am facing problem with inserting
insert into sample values('ganesh','welcome to india')
insert into sample values('ganesh','welcome to india's largest temple')
First statement is working fine but how to execute second statement?
Try this one -
IF OBJECT_ID(N'dbo.sample') IS NOT NULL
DROP TABLE dbo.[sample]
CREATE TABLE dbo.[sample]
(
id INT IDENTITY(1,1) PRIMARY KEY
, name VARCHAR(20)
, Yell_Your_self VARCHAR(2000)
)
INSERT INTO dbo.[sample]
VALUES
('ganesh', 'welcome to india'),
('ganesh', 'welcome to india''s largest temple')
Update3:
public int get(string val1,string val2)
{
using(SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
int i = 0;
using (SqlCommand cmd = new SqlCommand("INSERT INTO dbo.sample (name, Yell_Your_self) VALUES(#val1, #val2)", con))
{
cmd.Parameters.AddWithValue("#val1", val1);
cmd.Parameters.AddWithValue("#val2", val2);
i = cmd.ExecuteNonQuery();
}
con.Close();
return i;
}
}
Likely throwing an error on the apostrophe in the india's
insert into sample values('ganesh','welcome to india''s largest temple')
The issue is that you have a single quote in the string, and a single quote is a string delimiter in SQL.
Try:
INSERT INTO sample VALUES ('ganesh','welcome to india''s largest temple')
As you are already aware that the trouble SQL is facing is to escape an apostrophy in query, which is fixed i guess. To answer your second question about how to pass value from front end like C#, parametrized query is one of the good approach. As an alternative you can go with this one also which involves string manipulations to prepare a query:
public int get(string val1,string val2)
{
string temp = string.Concat(val1,"," + val2); // concatenate all your params
temp = temp.replace("'","''").replace(",","','"); // replace any single qoute with escaped single quote
string s="insert into sample values('" + temp + "')"; // append altered string in query
SqlCommand cmd = new SqlCommand(s,con);
con.Open();
int i = cmd.ExecuteNonQuery();
con.Close();
return i;
}
Hope it helps!
try this with passing dynamic value
insert into sample values(#name, N''' + #Yell_Your_self text + ''' )

Getting a result feedback from a stored procedure in Entity Framework

In a SQL Server 2008 I have a simple stored procedure moving a bunch of records to another table:
CREATE PROCEDURE [dbo].MyProc(#ParamRecDateTime [datetime])
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].Table2
SELECT
...,
...
FROM [dbo].Table1
WHERE RecDateTime <= #ParamRecDateTime
DELETE FROM [dbo].Table1
WHERE RecDateTime <= #ParamRecDateTime
END
Running it from within SQL Server Management Studio, I get the job done and return value = 0
DECLARE #return_value int
EXEC #return_value = dbo.MyProc #ParamRecDateTime = '2011-06-25 11:00:00.000'
SELECT 'Return Value' = #return_value
But when I call the same stored procedure from an app using Entity framework, I also get the job done but the return value is "-1":
int result = myrepository.MyProc(datetimePar);
MessageBox.Show(result.ToString());
I didn't manage to find an explanation for this error, but found this discouraging post, where it's said that there is no standard for this type of return codes in SQL Server.
What is the good, reliable way of getting know of a Stored Procedure execution result when calling it from Entity Framework and when the Stored Procedure doesn't return any entities?
One way to do it is to call ExecuteStoreCommand, and pass in a SqlParameter with a direction of Output:
var dtparm = new SqlParameter("#dtparm", DateTime.Now);
var retval = new SqlParameter("#retval", SqlDbType.Int);
retval.Direction = ParameterDirection.Output;
context.ExecuteStoreCommand("exec #retval = MyProc #dtparm", retval, dtparm);
int return_value = (int)retval.Value;
Originally I tried using a direction of ReturnValue:
retval.Direction = ParameterDirection.ReturnValue;
context.ExecuteStoreCommand("MyProc #dtparm", retval, dtparm);
but retval.Value would always be 0. I realized that retval was the result of executing the MyProc #dtparm statement, so I changed it to capture the return value of MyProc and return that as an output parameter.
using (dbContext db = new dbContext())
{
var parameters = new[]
{
new SqlParameter("#1","Input Para value"),
new SqlParameter("#2",SqlDbType.VarChar,4){ Value = "default if you want"},
new SqlParameter("#3",SqlDbType.Int){Value = 0},
new SqlParameter("#4","Input Para Value"),
new SqlParameter("#5",SqlDbType.VarChar,10 ) { Direction = ParameterDirection.Output },
new SqlParameter("#6",SqlDbType.VarChar,1000) { Direction = ParameterDirection.Output }
};
db.ExecuteStoreCommand("EXEC SP_Name #1,#2,#3,#4,#5 OUT,#6 OUT", parameters);
ArrayList ObjList = new ArrayList();
ObjList.Add(parameters[1].Value);
ObjList.Add(parameters[2].Value);
}
See OUTPUT attribute for SQL param of store procedure,
here
For future reference: I had the same issue but needed multiple OUTPUT variables. The solution was a combination of both answers. Below is a complete sample.
public void MyStoredProc(int inputValue, out decimal outputValue1, out decimal outputValue2)
{
var parameters = new[] {
new SqlParameter("#0", inputValue),
new SqlParameter("#1", SqlDbType.Decimal) { Direction = ParameterDirection.Output },
new SqlParameter("#2", SqlDbType.Decimal) { Direction = ParameterDirection.Output }
};
context.ExecuteStoreCommand("exec MyStoredProc #InParamName=#0, #OutParamName1=#1 output, #OutParamName2=#2 output", parameters);
outputValue1 = (decimal)parameters[1].Value;
outputValue2 = (decimal)parameters[2].Value;
}
Please note the Types used (decimal.) If another type is needed, remember to not only change it in the method argument list but also the SqlDbType.XXX.

Incorrect syntax near stored procedure error

I'm updating a long list of records. In my code, everything run as predicted until it execute the query. I get an
Incorrect syntax near 'TempUpdatePhysicalCityStateZip'
(my stored procedure name). I've tested it with SQL Server Management Studio and it runs fine. So, I'm not quite sure where I got it wrong. Below is my stored procedure and code:
ALTER PROCEDURE [dbo].[TempUpdateCityStateZip]
#StoreNo nvarchar (11),
#City nvarchar(50),
#State nvarchar(2),
#Zip nvarchar(5)
AS
BEGIN
SET NOCOUNT ON;
UPDATE StoreContact
SET City = #City, State = #State, Zip = #Zip
WHERE StoreNo = #StoreNo
END
Here is my code:
Dictionary<string, string> CityStateZipList = getCityStateZipList(dbPath);
using (SqlConnection conn = new SqlConnection(dbPath))
{
conn.Open();
SqlCommand cmdUpdate = new SqlCommand("TempUpdateCityStateZip", conn);
foreach (KeyValuePair<string, string> frKeyValue in CityStateZipList)
{
cmdUpdate.Parameters.Clear();
string[] strCityStateZip = frKeyValue.Value.Split(' ');
cmdUpdate.Parameters.AddWithValue("StoreNo", frKeyValue.Key.ToString());
foreach (String i in strCityStateZip)
{
double zipCode;
if (i.Length == 2)
{
cmdUpdate.Parameters.AddWithValue("State", i);
}
else if (i.Length == 5 && double.TryParse(i, out zipCode))
{
cmdUpdate.Parameters.AddWithValue("Zip", i);
}
else
{
cmdUpdate.Parameters.AddWithValue("City", i);
}
}
cmdUpdate.ExecuteNonQuery();
}
}
I believe you can get that puzzling error message if you don't specify the command type:
cmdUpdate.CommandType = CommandType.StoredProcedure;
Don't you need the # sign before the parameter?
cmdUpdate.Parameters.AddWithValue("#State", i);
FWIW, Thats kind of a dirty piece of code there, you will probably have many issues trying to maintain that. For performance reasons you may want to parse out the CityStateZipList before you open the connection, that way you aren't keeping it open longer than you need.

Resources