display multivalue attribute in gridView - c#

I have a table studentPhone that looks like the following:
phone studentID
2345678 1
0562436720 1
2254754 2
0546218611 2
I want to display its data in a gridView with sqlDataSource select query as:
SELECT phone, studentID FROM studentPhone WHERE (studentID IN (1))
but the gridView display only the firstPhone of the specified studentID. How can I solve that to display all phones for a specific ID?

SELECT phone, studentID FROM studentPhone WHERE (studentID = 1 )
If you want to display all the phone number of one ID in a single column then you have to write a store procedure.
Example:
create table test1
( phone varchar(30),
id int )
insert into test1(phone,id) values('2345678',1)
insert into test1(phone,id) values('0562436720',1)
Create Procedure getStudentsByID
#ID
AS
BEGIN
declare #test varchar(max)
select #test = ISNULL(#test+',','')+ test1.phone from test1 where test1.id = #ID
select #test
This will return you the comma separated list of all the phone numbers of the given ID.

Related

How to accept a list into an SQL TableAdapter query using C#?

I'd like to perform an SQL query on a data table and return records with IDs that match any one of the IDs in a particular list (which would be passed in as a parameter to the SQL TableAdapter query). This ID which is being checked is a foreign key in the table. The following is the code am I using, only including what is relevant:
SELECT BookingID, DogID
FROM Booking
WHERE DogID IN (...)
Ideally, I'd like to be able to pass in a list of type string.
You can pass id as , separated string and use User Define function to split that:
try below:
UDF
CREATE FUNCTION [dbo].[Udf_stringtolist] (#List NVARCHAR(max),
#Delimeter NVARCHAR(10))
returns #tmpListTable TABLE (
value NVARCHAR(max))
AS
BEGIN
DECLARE #DelimPosition INT
SELECT #DelimPosition = Charindex(#Delimeter, #List)
WHILE #DelimPosition > 0
BEGIN
INSERT INTO #tmpListTable
(value)
VALUES (Cast(Ltrim(Rtrim(LEFT(#List, #DelimPosition - 1))) AS
VARCHAR(
100)))
SELECT #List = RIGHT(#List, Len(#List) - #DelimPosition),
#DelimPosition = Charindex(#Delimeter, #List)
END
IF Len(#List) > 0
INSERT INTO #tmpListTable
(value)
VALUES (Cast(Ltrim(Rtrim(#List)) AS VARCHAR(100)))
RETURN
END
Use the function:
DECLARE #idList NVARCHAR(max)=',1,2,3,4,5,6';
SELECT bookingid,
dogid
FROM booking
WHERE dogid IN (SELECT *
FROM [dbo].[Udf_stringtolist] (#idList, ',')
ORDER BY 1)
There are 2 ways.
Comma separated ids - which will lead to performance issue while split it
XML - is best approach.

How to split only one row value and insert into multiple columns using stored procedure, parameter value is from C#

ALTER PROCEDURE [dbo].[ProcTeamInfoById]
(#id INT,
#txtName VARCHAR(50),
#phone VARCHAR(100),
#contactname VARCHAR(100),
#address VARCHAR(300),
#email VARCHAR(100),
#captain VARCHAR(100),
#requirements VARCHAR(50))
AS
BEGIN
IF #id = -1
BEGIN
DECLARE #teamID VARCHAR(MAX);
INSERT INTO TeamDetails(TeamName, Phone, ContactName, Address, Email, captain)
VALUES (#txtName, #phone, #contactname, #address, #email, #captain)
SET #teamID = SCOPE_IDENTITY();
// Here now I need to add to different table...
// checkbox checked values
INSERT INTO teamrequirements (teamid, requirement, value)
VALUES (#teamID, #requirements, 1)
// Here I am getting 1, bats, Gloves, 1
END
ELSE
UPDATE TeamDetails
SET TeamName = #txtName, Phone = #phone,
ContactName = #contactname,
Address = #address, Email = #email,
WHERE TeamId = #id
END
I need like this how to modify stored procedure
1, bats,gloves,1
I need to insert as
1 bats 1
2 gloves1
If I need to update the above it should be like
1 bats 1
If I updating with no values it should be like
1 '' ''
My stored procedure inserts into two tables. While adding into teamrequirements table, I need to split one column value into multiple columns where I commented. I need to modify the stored procedure to insert into multiple columns and records
in the teamrequirements table.
How to do it?
While adding a team is added into the teamdetails table, and I have checkbox like Requirements if I check that I can select another two checkboxes, when both checkboxes are checked, two records to be inserted in teamrequirements, example , i wil have teamid, requirement, value...example 1,bats,Gloves,1 this should insert as 2 records Like
12,1 bat , 1 // 12 is record id in teamrequirements
13,1,Gloves , 1 // 13 is record id in teamrequirements
Please help...
What if it is Update in the same procedure ..
update teamrequirements set requirement= #reuirement , value = 1 where teamid = #id in this case , if i add those two records bats gloves in database i am adding records , what if i need to clear those added records using update statement in the same procedure
You can use any of the split function over the internet or create your own and use it. Below code has been written according to split function in FnSplitString.
You created a split function in your database. This function will return 1 or more values from your string provided. This is your #requirements variable.
IF(LEN(#requirements) > 0)
BEGIN
INSERT INTO teamrequirements (teamid, requirement, value)
SELECT #teamID, splitdata, '1' FROM dbo.[fnSplitString](#requirements,',')
END
ELSE
BEGIN
INSERT INTO teamrequirements (teamid, requirement, value)
VALUES (#teamID, '', '')
END
SQL 2016:
JSON support is there now. So, you can pass string as json and take 2 values into key value table, and insert it directly. No need to split.
FOR UPDATE:
You can take this split string data in a table variable. Update data from table variable as source into main table, with a JOIN condition.
DECLARE #id INT = 40
DECLARE #data TABLE
(
Id INT,
Requirement VARCHAR(50),
Value INT
)
DECLARE #requirements VARCHAR(50) = 'bat,gloves,ball'
INSERT INTO #data
SELECT #id, splitdata, 1 FROM dbo.[fnSplitString](#requirements,',')
SELECT * FROM #data
-- SOMETHING LIKE THIS CAN BE YOUR UPDATE QUERY
UPDATE a SET
value = b.Value
FROM teamrequirements a INNER JOIN #data b ON a.id = b.Id
and a.requirement = b.Requirement
MERGE SAMPLE:
MERGE teamrequirements AS TARGET
USING #data AS SOURCE
ON TARGET.id = SOURCE.Id AND TARGET.requirement = SOURCE.Requirement
--When records are matched, update
--the records if there is any change
WHEN MATCHED THEN
UPDATE SET TARGET.value = SOURCE.Value
--When no records are matched, insert
--the incoming records from source
--table to target table
WHEN NOT MATCHED BY TARGET THEN
INSERT (teamid, requirement, value)
VALUES (SOURCE.Id, SOURCE.Requirement, SOURCE.Value);
First, it would be better to use table valued parameters for this.
Without that, you can split the string (this demo uses delimitedsplit8k by Jeff Moden) , and you could use merge to handle changes. It makes sense to move this into its own procedure and call that procedure from your current one.
TL;DR: rextester demo: http://rextester.com/PVX88970
The TeamRequirements_Merge procedure:
create procedure dbo.TeamRequirements_Merge (
#TeamId int
, #requirements varchar(8000)
) as
begin;
set nocount, xact_abort on;
/* it would be much better to use table valued parameters for this */
;with t as (
select TeamId, Requirement, Value
from TeamRequirements
where TeamId = #TeamId
)
, s as (
select
TeamId = #TeamId
, Requirement = coalesce(s.item,'') -- since you want blanks
, Value = 1
from dbo.[delimitedsplit8K](#requirements,',') s
)
merge into t with (holdlock)
using s
on t.TeamId = s.TeamId
and t.Requirement = s.Requirement
when matched and t.value <> s.value
then update set t.value = s.value
when not matched by target
then insert (TeamId, Requirement, Value)
values (s.TeamId, s.Requirement, s.Value)
when not matched by source
then delete
--output $Action, inserted.*, deleted.* /* for testing */
;
end;
go
The revised ProcTeamInfoById procedure:
create procedure [dbo].[ProcTeamInfoById] (
#id int
, #txtName varchar(50)
, #phone varchar(100)
, #contactname varchar(100)
, #address varchar(300)
, #email varchar(100)
, #captain varchar(100)
, #requirements varchar(8000)
) as
begin;
if #id = -1
begin;
insert into TeamDetails(TeamName, Phone, ContactName, Address, Email, captain)
values (#txtName, #phone, #contactname, #address, #email, #captain);
set #id = scope_identity();
end;
else
begin;
update TeamDetails
set TeamName = #txtName, Phone = #phone,
ContactName = #contactname,
Address = #address, Email = #email
where TeamId = #id;
end;
exec dbo.TeamRequirements_Merge #id, #requirements;
end;
go
splitting strings reference:
Tally OH! An Improved SQL 8K “CSV Splitter” Function - Jeff Moden
Splitting Strings : A Follow-Up - Aaron Bertrand
Split strings the right way – or the next best way - Aaron Bertrand
string_split() in SQL Server 2016 : Follow-Up #1 - Aaron Bertrand
Ordinal workaround for **string_split()** - Solomon Rutzky
merge reference:
Use Caution with SQL Server''s MERGE Statement - Aaron Bertrand
UPSERT Race Condition With Merge - Dan Guzman
An Interesting MERGE Bug - Paul White
Can I optimize this merge statement - Aaron Bertrand
If you are using indexed views and MERGE, please read this! - Aaron Bertrand
The Case of the Blocking Merge Statement (LCK_M_RS_U locks) - Kendra Little
Writing t-sql merge statements the right way - David Stein
Again, it would be better to use table valued parameters for this:
Table Valued Parameters reference:
Table-Valued Parameters - msdn
User-Defined Table Types - msdn
SQL Server 2008 Table-Valued Parameters and C# Custom Iterators: A Match Made In Heaven! - Leonard Lobel
Table Value Parameter Use With C# - Jignesh Trivedi
Using Table-Valued Parameters in SQL Server and .NET - Erland Sommarskog
Maximizing Performance with Table-Valued Parameters - Dan Guzman
Maximizing throughput with tvp - sqlcat
How to use TVPs with Entity Framework 4.1 and CodeFirst

TSQL generating update statement for table based on condition

How to generate update statement on the whole table with some condition ? For example I have table
and I would like to specify date (for this example '3/16/2016') and generate something like following Update
UPDATE TableName SET ColumnValue = 30 AND ModifiedDate = '2016-03-17' WHERE Id = 2
If there will be more changes after specified date, I would like to generate all the updates for these changes.
Is there some easy solution or I have to script all this by some customized C# script ?
If you have 2 identical tables and need to update one of the tables based on changes happed after a particular timestamp (#Date) in another table then you can use below query.
UPDATE T1
SET T1.ColumnValue=T2.ColumnValue,T1.ModifiedDate=T2.ModifiedDate
FROM Table1 T1 inner join Table2 T2 on T1.ID=T2.ID
WHERE T2.ModifiedDate>=#Date
If you just want to generate update statements, you could do something like this:
declare #afterDate date = '20160316';
select update_statements = 'update table t set columnvalue = '
+convert(varchar(10),columnvalue)
+', modifieddate = '''
+replace(convert(varchar(10),modifieddate,120),'-','')+''''
+' where id = '+convert(varchar(10),id)+';'
from t
where modifieddate > #afterdate;
rextester demo: http://rextester.com/MZQ68677
returns:
+------------------------------------------------------------------------------+
| update_statements |
+------------------------------------------------------------------------------+
| update table t set columnvalue = 30, modifieddate = '20160317' where id = 2; |
+------------------------------------------------------------------------------+
This gives the trigger to track all the updates for a table. Based on table structure you can add required columns in the tracking table.
CREATE TABLE EMP(ID int, NAME VARCHAR(20), SALARY MONEY)
CREATE TABLE TrackUpdate (Id int identity, updatestmt varchar(500), DateCreated datetime)
GO
INSERT INTO EMP
VALUES
(1, 'A', 10),(2, 'E',40 ),(3,'B',5),(4,'F',40),(5,'I',50)
GO
ALTER TRIGGER TR_EMP ON EMP
INSTEAD OF UPDATE
AS
BEGIN
declare #Name varchar(10)
declare #Salary MONEY
SELECT #Name=Name,#Salary=Salary FROM inserted
insert into TrackUpdate values ('update Emp SET E.Name='''+#Name+''', '+'E.Salary='+CAST(#Salary as varchar(20)),getdate())
update E SET E.Name=I.Name, E.Salary=I.Salary
FROM EMP E inner join inserted I on I.ID=E.ID
END
update EMP set Name='D' where ID=4
select updatestmt from TrackUpdate
--drop table EMP
--drop table TrackUpdate

Trigger after Insert value from another table

I have two tables Employee and Employee Log, I created a trigger after insert, I have no problem with my after insert trigger using entities or values from employee, to insert directly to Log table, but how would I insert value from another table? like Admin_ID. I want a log table with transaction, datetime and who created.
Thank you.
CREATE TRIGGER emp_log_af AFTER INSERT ON emp
FOR EACH ROW
BEGIN
INSERT INTO emp_log (action,id,ts, ad_id)
VALUES('create',NEW.id,NOW());
END;
its not possible with trigger what i did was get the max(id) to do that i created a stored procedure.
DELIMITER $$
CREATE PROCEDURE sp_insert_user_log
(
IN ia Varchar(12),
IN ie INT,
IN ix datetime
)
BEGIN
DECLARE id INT DEFAULT 0;
SELECT MAX(user_id) INTO id FROM user ORDER BY user_id DESC LIMIT 1;
BEGIN
INSERT INTO `user_log`(`action`, `user_id`, `employee_id`, `ts`) VALUES (ia, id, ie, ix);
END;
END$$
DELIMITER ;
DELIMITER $$

Random Row Number Selection

I am working on a website that does random selections of employees for random drug test. I am trying to figure out a report/ code using SQL Server 2008, ASP.NET, and C#.
Here is an example of what I have worked on so far:
I need to do is generate a report of all employees for a specific company where the employees are assign a number. Example of this code is as follows:
SELECT
dbo.names2.ssn, dbo.names2.firstname, dbo.names2.lastname,
ROW_NUMBER() over(order by dbo.names2.ssn) as RowNumber
FROM
dbo.names2
WHERE
dbo.names2.code = 8562
This query return 12 records number 1-12 with the Employees social security number, first name, and last name.
I now need to figure out a query so that when I go to my asp.net webpage and enter that I need 5 employees to be randomly tested that I get a query that returns the row number the employee is associated with in the query above on one page of the report, and on the second page of the report return the number assigned in the query above along with the employees SSN, First, and last name.
Thanks,
ty
I would ORDER BY NEWID() which generates a random GUID and SELECT TOP 5.
Edited. This query has 2 return results. 1 is the full list of employees and the other is just the list of 5 randomly selected numbers that corresponds to the rownum on the employee list.
IF (OBJECT_ID(N'tempdb..#tempTable') IS NOT NULL)
DROP TABLE #tempTable ;
CREATE TABLE #tempTable
(
RowNum INT ,
SSN VARCHAR(16) ,
FirstName VARCHAR(64) ,
LastName VARCHAR(64)
);
INSERT INTO [#tempTable]
([RowNum] ,
[SSN] ,
[FirstName] ,
[LastName]
)
SELECT ROW_NUMBER() OVER(ORDER BY dbo.names2.ssn) AS RowNum ,
dbo.names2.ssn ,
dbo.names2.firstname ,
dbo.names2.lastname
FROM dbo.names2
WHERE dbo.names2.code = 8562
SELECT [RowNum] ,
[SSN] ,
[FirstName] ,
[LastName]
FROM [#tempTable] AS tt
SELECT TOP 5 RowNum
FROM [#tempTable] AS tt
ORDER BY NEWID()

Categories