Pass parameter that will return all rows - asp.net

I'm working on an ASP.NET application that will call a simple Stored Procedure. The SP looks something like this:
Select *
from empTable
where ID = #ID AND Department = #DeptID
and status = #status
and role = #role
The ASP.NET application will pass a value to the each parameter in the stored procedure. Every parameter can be null or have a value. However, if the user enter nothing (null or empty), it should return everything in that empTable as if Select * from empTable with no Where clause.
However, due to the orders from the management:
I CANNOT change the code in ASP.NET application.
I CANNOT use dynamic SQL.
I'm only allowed to modify the stored procedure.
Is there any way I can work around this?

Make the parameter optional by changing the WHERE clause and assign a default value.
CREATE PROCEDURE MyProc
#ID INT = NULL
AS
Select * from empTable where ID = ISNULL(#ID, ID);

Case statements work...use case to set 1 = 1 when #id = 'all' (or whatever you want the #id to equal for all)
Select * from empTable where
case when #id = 'all' then 1 else id end
=
case when #id = 'all' then 1 else #id
JodyT's answer is better...this works, but not as pretty

Related

Return value to textbox from stored procedure

Having trouble returning the value ID value I need for output back to the textbox in the form. Webforms and ADO.net
I tried adding a param identity as an int and OUT clause, while setting identity = scope_identity and returning the value then using the pattern my team is currently using for ExecuteNonQuery with anonymous parameter classes passing in values and tried passing the #identity value to the textbox.text for the id.
DataManager.Db.ExecuteNonQuery("DefaultConnection", "usp_CreateNewSalesTerritory",
new SqlParameter("#orgId", orgId),
new SqlParameter("#identity", salesTerritoryIdTextBox.Text),
new SqlParameter("#salesTerritoryName", salesTerritories.Name),
new SqlParameter("#createdBy", salesTerritories.CreatedBy),
new SqlParameter("#createdDate", salesTerritories.CreatedDate),
new SqlParameter("#updatedBy", salesTerritories.UpdatedBy),
new SqlParameter("#updatedDate", salesTerritories.UpdatedDate),
new SqlParameter("#isActive", salesTerritories.IsActive));
CREATE PROCEDURE dbo.usp_CreateNewSalesTerritory
#orgId VARCHAR(255),
#salesTerritoryName VARCHAR(255),
#createdBy VARCHAR(255),
#createdDate DATETIME,
#updatedBy VARCHAR(255),
#updatedDate DATETIME,
#isActive BIT,
#identity INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO SalesTerritory (OrganizationId, Name, IsActive,
CreatedBy, CreatedDate, UpdatedBy, UpdatedDate)
VALUES (#orgId, #salesTerritoryName, #isActive,
#createdBy, #createdDate, #updatedBy, #updatedDate);
--SELECT SCOPE_IDENTITY();
--RETURN SCOPE_IDENTITY();
--SELECT ##IDENTITY;
SET #identity = SCOPE_IDENTITY()
END;
RETURN #identity
I expected to get the new inserted ID value for that record, instead, I get the default value of 0 on the screen
Normally, you would call such a stored procedure in "pure" ADO.NET using the .ExecuteNonQuery() method on the SqlCommand object - since it's an INSERT statement.
But now, your stored procedure is actually returning some data - so you really need to treat this like a "normal" SELECT stored procedure.
Assuming you're always returning just the SCOPE_IDENTITY() value - preferably like this:
SELECT SCOPE_IDENTITY();
which is just one single value - you can use the .ExecuteScalar() method on the SqlCommand object - something like this:
object returned = sqlCmd.ExecuteScalar();
if (returned != null)
{
int newIdValue = Convert.ToInt32(returned);
}
// else -> nothing was returned, so most likely no row has been inserted -> handle it appropriately
So maybe you already have a "wrapper" method for .ExecuteScalar() on your DataManager.Db object - or maybe you need to add it. Give it a try - I'm pretty sure this will solve the issue.
I would avoid using the RETURN ... statement - SQL Server stored procedure by default will always return the number of rows that were affected by your stored procedure - don't change that "standard" behavior, if you can.

Incorrect default value passed to the SQL Server database

I have set my column to int not null default 1... but whenever I save my record, it sets default value for that record to be 0.
I am not setting it anywhere. I don't know where I am making a mistake.
I have debugged my code , and when I am passing new entity object it is setting default value for not null to 0 .May be it is something with LINQ, But I don't know how to handle it.I don't want to explicitly assign value.
Thanks!
For sql-server, you can use SQL Server Profiler to catch all the scripts you run into the DB.
This may show you some details
Try running this query, replacing the 'myTable' and 'myColumn' values with your actual TABLE and COLUMN names, and see what's returned:
SELECT
OBJECT_NAME(C.object_id) AS [Table Name]
,C.Name AS [Column Name]
,DC.Name AS [Constraint Name]
,DC.Type_Desc AS [Constraint Type]
,DC.Definition AS [Default Value]
FROM sys.default_constraints DC
INNER JOIN sys.Columns C
ON DC.parent_column_id = C.column_id
AND DC.parent_object_id = C.object_id
WHERE OBJECT_NAME(DC.parent_object_id) = 'myTable'
AND COL_NAME(DC.parent_object_id,DC.parent_column_id) = 'myColumn'
;
Should return something like this:
[Table Name] [Column Name] [Constraint Name] [Constraint Type] [Default Value]
-------------------------------------------------------------------------------------------
myTable myColumn DF_myTable_myColumn DEFAULT_CONSTRAINT ('0')
If the [Default Value] returned is indeed (1), then it means that you have set the constraint properly and something else is at play here. It might be a trigger, or some other automated DML that you've forgotten/didn't know about, or something else entirely.
I am not the world's biggest fan of using a TRIGGER, but in a case like this, it could be handy. I find that one of the best uses for a TRIGGER is debugging little stuff like this - because it lets you see what values are being passed into a table without having to scroll through mountains of profiler data. You could try something like this (again, switching out the myTable and myColumn values with your actual table and column names):
CREATE TABLE Default_Check
(
Action_Time DATETIME NOT NULL DEFAULT GETDATE()
,Inserted_Value INT
);
CREATE TRIGGER Checking_Default ON myTable
AFTER INSERT, UPDATE
AS
BEGIN
INSERT INTO Default_Check (Inserted_Value)
SELECT I.myColumn
FROM Inserted I
;
END
;
This trigger would simply list the date/time of an update/insert done against your table, as well as the inserted value. After creating this, you could run a single INSERT statement, then check:
SELECT * FROM Default_Check;
If you see one row, only one action (insert/update) was done against the table. If you see two, something you don't expect is happening - you can check to see what. You will also see here when the 0 was inserted/updated.
When you're done, just make sure you DROP the trigger:
DROP TRIGGER Checking_Default;
You'll want to DROP the table, too, once it's become irrelevant:
DROP TABLE Default_Check;
If all of this still didn't help you, let me know.
In VB use
Property VariableName As Integer? = Nothing
And
In C# use
int? value = 0;
if (value == 0)
{
value = null;
}
Please check My Example:
create table emp ( ids int null, [DOJ] datetime NOT null)
ALTER TABLE [dbo].[Emp] ADD CONSTRAINT DF_Emp_DOJ DEFAULT (GETDATE()) FOR [DOJ]
1--Not working for Default Values
insert into emp
select '1',''
2 ---working for Default Values
insert into emp(ids) Values(13)
select * From emp

How to have a MySQL procedure return a boolean?

I want to create a procedure that takes in a string, searches the table and the specified column for that string, and returns a 1 if it finds it and a zero if it does not. I am relatively new to SQL and do not know the syntax or commands very well. I want something like this:
CREATE PROCEDURE dbo.GetUsername
(
#Username NCHAR(10)
)
AS
#boolVariable
SELECT #Username FROM Accounts
RETURN #boolVariable
You don't return a value, but instead supply that in a result set.
CREATE PROCEDURE GetUsername
(
#Username NCHAR(10)
)
AS
SELECT Username FROM Accounts WHERE Username = #UserName;
In your calling code, simply check for the existence of a row in the result set.
I'm not sure if you're looking for mysql or mssql solution.
delimiter //
drop procedure if exists search_string //
create procedure search_string (in str varchar(100))
begin
declare b,r bool;
select count(*) into r from your_table where your_field = str;
if r > 0 then
set b = 1;
else
set b = 0;
end if;
select b;
end; //
delimiter //
call search_string('searched_string');

Cannot implicitly convert type 'System.Data.Linq.ISingleResult<CustomeProcedureName> to 'int'

Sorry for this simple question .
I have a Stored Procedure that return an int value , I'm trying to call this sp from my asp.net linq to sql project .
int currentRating = db.sproc_GetAverageByPageId(pageId);
But i get this error :
Cannot implicitly convert type `'System.Data.Linq.ISingleResult<PsychoDataLayer.sproc_GetAverageByPageId> to 'int' .`
Edit 1
The solution that friends implied didn't work . All the time it return 0
For more information i put my stored procedure here :
ALTER procedure [dbo].[sproc_GetAverageByPageId](
#PageId int )
as
select (select sum(score) from votes where pageId = #PageId)/(select count(*) from votes where pageId=#PageId)
You should inspect the ReturnValue property.
Perhaps the following works better?
int currentRating = (int)db.sproc_GetAverageByPageId(pageId).ReturnValue;
Update: since your stored proc returns a resultset instead of using a return statement the actual data will be available as an element in the enumerable returned by db.sproc_GetAverageByPageId(pageId). If you inspect the ISingleResult<T> type, you'll see that it inherits IEnumerable<T> which indicates that you can enumerate the object to get to the data, each element being of type T.
Since the sproc does a SELECT SUM(*) ... we can count on the resultset to always contain one row. Thus, the following code will give you the first (and only) element in the collection:
var sumRow = db.sproc_GetAverageByPageId(pageId).Single();
Now, the type of sumRow will be T from the interface definition, which in your case is PsychoDataLayer.sproc_GetAverageByPageId. This type hopefully contains a property that contains the actual value you are after.
Perhaps you can share with us the layout of the PsychoDataLayer.sproc_GetAverageByPageId type?
Looks like you're actually after the ReturnValue. You may need to cast it to System.Data.Linq.ISingleResult if it isn't already, then cast ReturnValueto int.
This is actually returning an ISingleResult
int currentRating = (int) db.sproc_GetAverageByPageId(pageId).ReturnValue;
Change your sp to :
ALTER procedure [dbo].[sproc_GetAverageByPageId](
#PageId int )
as
return (select sum(score) from votes where pageId = #PageId)/(select count(*) from votes where pageId=#PageId)
one more thing you can do:
ALTER procedure [dbo].[sproc_GetAverageByPageId](#PageId int ) as
select (select sum(score) from votes where pageId = #PageId)/(SELECT * FROM votes where pageId=#PageId)
WRITE >>
"select * From"<< instead of "select Count(*)"
select (select sum(score) from votes where pageId = #PageId)/(SELECT * FROM votes where pageId=#PageId)
and after that:
int currentRating = (int)db.sproc_GetAverageByPageId(pageId).count();

Passing a IS NOT NULL through a sqlparameter

I have a query in sql server 2008. That I want to either pass a value from the dropdownlist or IS NOT NULL (so it shows all of the values). What's the best way to handle this? I know you can't pass the string "IS NOT NULL" to the parameter. I'm a bit stuck on this one.
ASP.NET 3.5 and SQL Server 2008.
Assuming this is a stored procedure, say your parameter is called #Param1, have the parameter set to NULL to indicate IS NOT NULL, as follows:
SELECT ...
FROM ...
WHERE (
(#Param1 IS NULL AND field1 IS NOT NULL)
OR (field1 = #Param1)
)
Suggested by GSerg
Testing ISNULL(#Param1, field1) = field1 with the following:
DECLARE #test1 nvarchar(10) = 'testing',
#test2 nvarchar(10) = NULL; -- or 'random' or 'testing'
SELECT 1
WHERE ISNULL(#test2, #test1) = #test1;
Computations are showing as 1 for each case. This appears to be a better solution than my original answer.
You can use the like operator:
select * from table1 where name like #param
setting #param to % if you want not null values. But then you have to escape the %.

Resources