Procedure not creating the number - c#

I need to use this procedure and when I insert the new employee I need to create EmpID in database like A1001,A1002...
But when I using this procedure it shows error to pass EmpID.
Sql Procedure:
ALTER procedure [dbo].[addemp]
#EmpId nvarchar(10),
#EmpName nvarchar(50),
#EmpAddress nvarchar(50)
as
begin
declare #Totalcount int
declare #Count nvarchar(10)
select #Totalcount=(select COUNT(EmpID) from NewEmp)
if #Totalcount is null
set #Count='A'+CONVERT(nvarchar(10),1001)
else
set #Count='A'+CONVERT(nvarchar(10),1001+(#Totalcount))
insert into NewEmp([EmpId],[EmpName],[EmpAddress]) values (#Count,#EmpName,#EmpAddress)
end
C# Code:-
protected void Button1_Click(object sender, EventArgs e)
{
string cs = ConfigurationManager.ConnectionStrings["Emp"].ConnectionString;
SqlConnection scon = new SqlConnection(cs);
SqlCommand cmd = new SqlCommand("addemp", scon);
cmd.CommandType = CommandType.StoredProcedure;
scon.Open();
cmd.Parameters.AddWithValue("#EmpName",TextBox2.Text);
cmd.Parameters.AddWithValue("#EmpAddress", TextBox3.Text);
cmd.ExecuteNonQuery();
}

As you are not going to use declared parameter #EmpId in SP, so please remove #EmpId parameter from SP
OR
Set default value : #EmpId=''
create procedure [dbo].[addemp]
#EmpId nvarchar(10)='',
#EmpName nvarchar(50)='',
#EmpAddress nvarchar(50)=''
as
begin
declare #Totalcount int
declare #Count nvarchar(10)
select #Totalcount=(select COUNT(EmpID) from NewEmp)
if #Totalcount is null
set #Count='A'+CONVERT(nvarchar(10),1001)
else
set #Count='A'+CONVERT(nvarchar(10),1001+(#Totalcount))
insert into NewEmp([EmpId],[EmpName],[EmpAddress]) values (#Count,#EmpName,#EmpAddress)
end

Don't use a stored procedure. SQL Server has the option of computed columns which you can use to your advantage.
This will also take care of duplicate EmpId problem that may arise when a row is deleted from the table.
Just declare your table like this:
CREATE TABLE NewEmp
(
ID BIGINT Identity(1, 1) PRIMARY KEY,
[EmpId] AS 'A' + CONVERT(VARCHAR(10), 1000 + ID),
[EmpName] VARCHAR(255),
[EmpAddress] VARCHAR(255)
-- add more columns here if required...
)
Now you don't need to use any stored procedure etc. to generate your EmpId; it will be computed automatically.
You can use simple insert statement to add records to the table.
For example:
INSERT INTO NewEmp ([EmpName], [EmpAddress])
VALUES ('test name1', 'test address1')
INSERT INTO NewEmp ([EmpName], [EmpAddress])
VALUES ('test name2', 'test address2')
INSERT INTO NewEmp ([EmpName], [EmpAddress])
VALUES ('test name3', 'test address3')
INSERT INTO NewEmp ([EmpName], [EmpAddress])
VALUES ('test name4', 'test address4')
INSERT INTO NewEmp ([EmpName], [EmpAddress])
VALUES ('test name5', 'test address5')
INSERT INTO NewEmp ([EmpName], [EmpAddress])
VALUES ('test name6', 'test address6')
SELECT * FROM NewEmp
Output:
|----| ----- | ---------- |---------------|
| ID | EmpId | EmpName | EmpAddress |
|----| ----- | ---------- |---------------|
| 1 | A1001 | test name1 | test address1 |
| 2 | A1002 | test name2 | test address2 |
| 3 | A1003 | test name3 | test address3 |
| 4 | A1004 | test name4 | test address4 |
| 5 | A1005 | test name5 | test address5 |
| 6 | A1006 | test name6 | test address6 |

You are not passing EmpId for the procedure, ether give the id or change procedure so that EmpId dosen't need to be given

Create Table NewEmp
(
EmpId nvarchar(10),
EmpName Varchar(255),
EmpAddress Varchar(255),
MaxID INt
)
Declare #EmpId NVARCHAR(10),
#EmpName NVARCHAR(50),
#EmpAddress NVARCHAR(50),
#Count NVARCHAR(10),
#MaxID INT
SET #EmpId = NULL
SET #EmpName ='Alfaiz'
SET #EmpAddress ='Worli'
SELECT #MaxID=Max(MaxID) FROM NewEmp
IF #MaxID Is NUll
SET #MaxID=1
Else
Select #MaxID = Max(MaxID) + 1 FROM NewEmp
IF #MaxID is null
SET #Count='A'+Convert(VARCHAR(25),1001)
ELSE
SET #Count='A'+CONVERT(VARCHAR(25),1000 + #MaxID)
INSERT INTO NewEmp
([EmpId],[EmpName],[EmpAddress],MaxID)
VALUES
(#Count,#EmpName,#EmpAddress,#MaxID)

Related

Fetch data from SQL table using Join with additional column according to Join

I have to tables those are connected with foreign key relation
Address Table
id | address| country
1 | xyz | USA
2 | xyz | IND
Employee Table
id | name | company | Postal_address | Visiting_address
1 | Test | xyz | 1 | 2
How can I display Linked address to Employee using a SQL query like
Address | Country | Address Type
xyz | USA | Postal
xyz | IND | Visting
Is their any possible way to display linked address of any employee as list with Address type name using a SQL Server query or C#?
You can use SQL UNION and UNION ALL Keywords to achieve it, Live demo here
DECLARE #Address AS TABLE(id int, address varchar(50), country varchar(50))
INSERT INTO #Address
VALUES(1, 'xyz', 'USA'),
(2, 'xyz', 'IND')
DECLARE #Employee AS TABLE(id int, name varchar(50), company varchar(50), Postal_address int, Visiting_address int)
INSERT INTO #Employee
VALUES(1,'Test', 'xyz', 1, 2)
SELECT a.address, a.country, 'Postal' AS Address_Type
FROM #Employee e
INNER JOIN #Address a on a.id = Postal_address
WHERE e.id = 1
UNION ALL
SELECT a.address, a.country, 'Visting' AS Address_Type
FROM #Employee e
INNER JOIN #Address a on a.id = Visiting_address
WHERE e.id = 1
Output
address country Address_Type
xyz USA Postal
xyz IND Visting
I have tried with UNPIVOT. Read more on UNPIVOT.
The sample code is given below for reference.
CREATE TABLE #address (
id INT
,address VARCHAR(255)
,country VARCHAR(20)
);
CREATE TABLE #Employee (
id INT
,name VARCHAR(20)
,company VARCHAR(20)
,Postal_address INT
,visiting_address INT
);
INSERT INTO #address
VALUES (1 ,'xyz' ,'USA') ,( 2 ,'xyz' ,'India');
INSERT INTO #Employee
VALUES ( 1 ,'test' ,'xyz' ,1 ,2 );
WITH CTE_AddressUnpivot
AS (
SELECT name
,address_Type
,address_id
FROM (SELECT *
FROM #Employee
) AS src
UNPIVOT(address_id FOR address_Type IN ([postal_Address], [visiting_address])) AS addressUnpivot
)
SELECT addr.address
,addr.country
,CASE unp_addr.address_Type
WHEN 'Postal_address' THEN 'Postal'
WHEN 'visiting_address' THEN 'Visiting'
END AS Address_Type
FROM #address AS addr
JOIN CTE_AddressUnpivot AS unp_addr ON addr.id = unp_addr.address_id
You could also try with LEFT JOINs and COALESCE, like below:
declare #Address table (id int, address varchar(10), country varchar(10));
insert into #address values
(1,'xyz','USA'),
(2,'xyz','IND');
declare #Employee table (id int, name varchar(10),company varchar(10),Postal_address int,Visiting_address int);
insert into #employee values
(1, 'Test', 'xyz', 1, 2);
select a.address, a.country,
case when ePost.id is not null then 'Postal'
when eVisit.id is not null then 'Visiting'
else null end AddressType
from #address a
left join #employee ePost on a.address = ePost.company and a.id = ePost.Postal_address
left join #employee eVisit on a.address = eVisit.company and a.id = eVisit.Visiting_address

How to use join on TableAdapter

So I have a DataSet file with some TableAdapters where main query is just a select from all main columns
problem is that I want to make a join so i can get the string value from the parent table but i get incorrect input string format exception when i do this....
this is the adapters
| Inventory | | Employee |
| ID int | | ID int |
| employee int | ----- | Name nvarchar |
| warehouse int |
I tried to do this in a stored procedure and make the join clause
GO
IF OBJECT_ID('dbo.spx_SELECT_InventariosByCustomPaging') IS NOT NULL
DROP PROCEDURE spx_SELECT_InventariosByCustomPaging
GO
CREATE PROCEDURE spx_SELECT_InventariosByCustomPaging
#startIndex int,
#pageSize int
AS
BEGIN
SET NOCOUNT ON
SELECT ID, Name, Warehouse, DataCriacao
FROM (
SELECT InventarioID, xc.Name, xa.Warehouse, DataCriacao, ROW_NUMBER()
OVER(ORDER BY Colaborador DESC) AS rowNumber
FROM Inventory xi
LEFT JOIN Employee xc
ON xc.ID= xi.ID
LEFT JOIN xArmazem xa
ON xa.ArmazemID = xi.Armazem
) AS Inventario
WHERE rowNumber > #startIndex AND
rowNumber <= (#startIndex + #pageSize )
END
How can I get the Name column on Inventory DataTable?
Additional information: Input string was not in a correct format.Couldn't store in Inventory Column. Expected type is Int.

Optimal way to analyze user qualifications data (C# and SQL server)

I need to analyze data from SQL server table. Table contains data connected with qualifications of all employyes in the company and has the following structure (simplified):
| User | Qualification | DateOfQualificationAssignment |
| user000 | Junior | 2014-01-15 |
| user000 | Middle | 2014-02-15 |
| user001 | Middle | 2014-02-02 |
| user001 | Senior | 2014-03-18 |
| user002 | Senior | 2014-02-19 |
| user003 | Junior | 2014-03-04 |
I need the way to determine number of employees having given qualification for the concrete date. It should be some sort of analyze("Qualification", "Date") function returning the folowing for these types of input data:
analyze("Junior", '2014-01-20') - returns 1 (it is user user000)
analyze("Junior", '2014-02-20') - returns 0 (because user000 became Middle on 2014-02-15)
analyze("Middle", '2014-02-25') - returns 2 (because user000 and user001 are having Middle qualification on 2014-02-25)
analyze("Middle", '2014-03-28') - returns 1 (user000 is still Middle, but user001 became Senior on 2014-03-18)
Currently I have no idea how to handle this efficiently. What approach can be used to achieve my goal?
Think this should satisfy your requirements:
create function dbo.analyze(#qualification varchar(50), #date date)
returns int
as
begin
declare #result int;
with cte
as
(
select t.*, rank() over (partition by t.[User] order by t.DateOfQualificationAssignment desc) r
from theTable t -- no clue what the real table is named
where t.DateOfQualificationAssignment < #date
)
select #result = count(*)
from cte
where cte.r = 1 and cte.Qualification = #qualification
return #result;
end
go
Tested with your data:
create table theTable
(
[User] varchar(50) not null,
Qualification varchar(50) not null,
DateOfQualificationAssignment date not null
)
go
insert into theTable([User],Qualification,DateOfQualificationAssignment)
values
('user000','Junior','20140115'),
('user000','Middle','20140215'),
('user001','Middle','20140202'),
('user001','Senior','20140318'),
('user002','Senior','20140219'),
('user003','Junior','20140304')
go
and the results:
select dbo.analyze('Junior','20140120') --returns 1
go
select dbo.analyze('Junior','20140220') --returns 0
go
select dbo.analyze('Middle','20140225') --returns 2
go
select dbo.analyze('Middle','20140328') --returns 1
go
Use row_number() over() in a derived table to enumerate the rows on DateOfQualificationAssignment descending partitioned by User where DateOfQualificationAssignment is less than the date you want to check on.
In the main query you count the rows with the enumerated value 1 and Qualification.
SQL Fiddle
MS SQL Server 2012 Schema Setup:
create table T
(
[User] char(7),
Qualification char(6),
DateOfQualificationAssignment date
)
insert into T values
('user000', 'Junior', '2014-01-15'),
('user000', 'Middle', '2014-02-15'),
('user001', 'Middle', '2014-02-02'),
('user001', 'Senior', '2014-03-18'),
('user002', 'Senior', '2014-02-19'),
('user003', 'Junior', '2014-03-04')
Query 1:
declare #Qualification char(6) = 'Middle'
declare #Date date = '2014-03-28'
select count(*)
from (
select T.Qualification,
row_number() over(partition by T.[User] order by T.DateOfQualificationAssignment desc) as rn
from T
where T.DateOfQualificationAssignment < #Date
) as T
where T.rn = 1 and
T.Qualification = #Qualification
Results:
| COLUMN_0 |
|----------|
| 1 |

How to pass parameter to IN in sql server

Here is my table named Employee
-----------------------
Column Name | Data Type
----------------------
ID | int
EmpId | nvarchar
Name | nvarchar
Salary | decimal
Have a look all the records of the table
------------------------------
ID | EmpId | Name | Salary
------------------------------
1 | 200 | Bulbul | 2000.00
2 | 201 | Ahmed | 2000.00
3 | 202 | Rakib | 2500.00
4 | 203 | Rubel | 3000.00
5 | 204 | Zia | 4000.00
Now if I want get all the records of a given employee id to the IN operator, I get the following result. It's just fine.
SELECT EmpId, Name, Salary
FROM Employee
WHERE EmpId IN ('200','201')
------------------------------
ID | EmpId | Name | Salary
------------------------------
1 | 200 | Bulbul | 2000.00
2 | 201 | Ahmed | 2000.00
But if I pass the employee id as parameter, then I don't get my desired results. Just get empty result.
DECLARE #Params AS NVARCHAR(MAX) = '''200'',''201'''
SELECT EmpId, Name, Salary
FROM Employee
WHERE EmpId IN (#Params)
------------------------------
ID | EmpId | Name | Salary
------------------------------
| | |
| | |
Now I need to get the following result using parameter in IN operator. My desired result is something like:
------------------------------
ID | EmpId | Name | Salary
------------------------------
1 | 200 | Bulbul | 2000.00
2 | 201 | Ahmed | 2000.00
Please help me to get my desire result. Thank in advance.
I suggest that use Table Type Parameter.
CREATE TYPE dbo.IdList AS TABLE (Id INT)
GO
DECLARE #Ids dbo.IdList
INSERT INTO #Ids(Id)VALUES(200),(201)
SELECT EmpId, Name, Salary
FROM Employee
WHERE EmpId IN (SELECT Id FROM #Ids)
Add below Table valued SQL Function fn_split:
CREATE FUNCTION [dbo].[fn_Split](#sText varchar(8000), #sDelim varchar(20) = ' ')
RETURNS #retArray TABLE (idx smallint Primary Key, value varchar(8000))
AS
BEGIN
DECLARE #idx smallint,
#value varchar(8000),
#bcontinue bit,
#iStrike smallint,
#iDelimlength tinyint
IF #sDelim = 'Space'
BEGIN
SET #sDelim = ' '
END
SET #idx = 0
SET #sText = LTrim(RTrim(#sText))
SET #iDelimlength = DATALENGTH(#sDelim)
SET #bcontinue = 1
IF NOT ((#iDelimlength = 0) or (#sDelim = 'Empty'))
BEGIN
WHILE #bcontinue = 1
BEGIN
--If you can find the delimiter in the text, retrieve the first element and
--insert it with its index into the return table.
IF CHARINDEX(#sDelim, #sText)>0
BEGIN
SET #value = SUBSTRING(#sText,1, CHARINDEX(#sDelim,#sText)-1)
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
--Trim the element and its delimiter from the front of the string.
--Increment the index and loop.
SET #iStrike = DATALENGTH(#value) + #iDelimlength
SET #idx = #idx + 1
SET #sText = LTrim(Right(#sText,DATALENGTH(#sText) - #iStrike))
END
ELSE
BEGIN
--If you can’t find the delimiter in the text, #sText is the last value in
--#retArray.
SET #value = #sText
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
--Exit the WHILE loop.
SET #bcontinue = 0
END
END
END
ELSE
BEGIN
WHILE #bcontinue=1
BEGIN
--If the delimiter is an empty string, check for remaining text
--instead of a delimiter. Insert the first character into the
--retArray table. Trim the character from the front of the string.
--Increment the index and loop.
IF DATALENGTH(#sText)>1
BEGIN
SET #value = SUBSTRING(#sText,1,1)
BEGIN
INSERT #retArray (idx, value)
VALUES (#idx, #value)
END
SET #idx = #idx+1
SET #sText = SUBSTRING(#sText,2,DATALENGTH(#sText)-1)
END
ELSE
BEGIN
--One character remains.
--Insert the character, and exit the WHILE loop.
INSERT #retArray (idx, value)
VALUES (#idx, #sText)
SET #bcontinue = 0
END
END
END
RETURN
END
And execute this query to get your output:
DECLARE #Params AS NVARCHAR(MAX) = '200,201'
SELECT EmployeeId, Name
FROM Employee
WHERE EmployeeId IN (select value from dbo.fn_Split(#Params,','))
Hope this helps!
Please try:
DECLARE #Params AS NVARCHAR(MAX) = '200,201'
exec ('SELECT EmpId, Name, Salary
FROM Employee
WHERE EmpId IN ('+#Params+')')
Finally I got my expected result doing something like:
CREATE TABLE #EmpTable
(
EmpId NVARCHAR (50) NULL
)
GO
DECLARE #Parameter AS NVARCHAR(MAX) = '(''201''),(''202'')'
DECLARE #SQL AS NVARCHAR(MAX) ='INSERT INTO #EmpTable (EmpId)VALUES' + #Parameter
EXEC (#SQL)
GO
SELECT EmpId, Name, Salary
FROM Employee
WHERE EmpId IN (SELECT EmpId FROM #EmpTable)

Getting rid of duplicated data in a GridView

I am getting duplicated data within my GridView, while pulling info from a SQL Server. I am using stored procedures and using some C# to set the parameters then using the SqlDataSource to put the sql data from the stored procedure into a GridView. I have looked at some other problems just like mine, but the SQL scripting was different than mine. I also know that my C# code works just fine, but I will post that also,
Here is the code:
SQL:
SELECT
people.name, comage.age, grad.date
FROM
people
INNER JOIN
(SELECT age, MAX(term)[term]
FROM comage GROUP BY date) comage ON people.term = comage.term
INNER JOIN
(SELECT date, MAX(term)[term]
FROM grad GROUP BY date) grad ON people.term = grad.term
WHERE
people.ID = #ID
ORDER BY
LastName
ASP.net:
<asp:GridView ID="grid" runat="server"></GridView>
C# code:
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "prcedureName";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
SqlParameter param = null;
param = cmd.Parameters.Add("#ID",System.Data.SqlDataType.NChar,255);
param.Direction = System.Data.ParameterDirection.Input;
param.value = in; //in is a string of some value
cmd.Connection = con; //con is a SqlConnection of some sort
SqlDataAdapter adp = new SqlDataAdapter(cmd);
SqlCommandBuilder command = new SqlCommandBuilder(adp);
DataTable data = new DataTable();
data.Locale = System.Globalization.CultureInfo.InvariantCulture;
adp.Fill(data);
grid.DataSource = data;
grid.AutoGenerateColumns = true;
grid.DataBind();
Here are the tables:
people table:
--------------------
|name | ID | term |
--------------------
|jeff | 0 | A |
|Jake | 1 | B |
--------------------
comage table:
--------------------
|Age | Term |
--------------------
|23 | A |
|25 | B |
--------------------
grad table:
--------------------
| Date | Term |
--------------------
| DEC | A |
| SUM | B |
--------------------
Are you sure that you don't have your aggregates backwards in your SQL? I would have expected it to be written more like this:
SELECT people.name, Max(comage.age) age, Max(grad.date) date
FROM people
INNER JOIN comage ON people.term = comage.term
INNER JOIN grad ON people.term = grad.term
WHERE people.ID = #ID
GROUP BY people.name
ORDER BY LastName
Which would produce a result set like this:
name | age | date
------------------
Jeff | 23 | DEC
Jake | 25 | SUM
I only get one record, based on the ID I submitted.
DECLARE #People TABLE ([Name] VARCHAR(10), ID INT, Term VARCHAR(10));
DECLARE #Comage TABLE (Age INT, Term VARCHAR(10));
DECLARE #Grad TABLE ([Date] VARCHAR(10), Term VARCHAR(10));
DECLARE #ID INT;
SET #ID = 0;
INSERT INTO #People VALUES ('Jeff', 0, 'A');
INSERT INTO #People VALUES ('Jake', 1, 'B');
INSERT INTO #Comage VALUES (23, 'A');
INSERT INTO #Comage VALUES (25, 'B');
INSERT INTO #Grad VALUES ('DEC', 'A');
INSERT INTO #Grad VALUES ('SUM', 'B');
SELECT age, MAX(term) [term]
INTO #Comage
FROM #Comage
GROUP BY [Age]
SELECT [Date], MAX(term) [term]
INTO #Grad
FROM #Grad GROUP BY [Date]
SELECT
p.name, c.age, g.[Date]
FROM
#People p
INNER JOIN #Comage c
ON c.term = p.term
INNER JOIN #Grad g
ON g.term = p.term
WHERE
p.ID = #ID
DROP TABLE #Comage
DROP TABLE #Grad

Categories

Resources