C# TableAdapter Fill/Get by Multiple IDs - c#

I'm faced with a little problem. The situation is:
I have a MSSQL table which contains IDs (int, identity, primarykey), and names (string).
This table is huge, so i don't want to fill the entire dataset just for one LINQ-query.
I have a search algorithm, which fills a List<int> with more than one ID.
I want to load the matching rows in a datagridview with the following code:
dataGridView1.DataSource = tbl_WorklistTableAdapter.GetDataByID(ids_here);
But i can't handle multiple IDs, just a single. The GetDataByID() code needs to be this (i think):
SELECT [ID]
,[NAME]
FROM [DataBase].[dbo].[tbl_Namelist]
WHERE ID IN (#searchterm)
However WHERE ID IN accepts comma-separated ints, like 1,2,3. But the #variable is just one int.
How should i convert string to ints?
Thank you, and sorry for bad eng. :)

In that case you need to change in sql so you need to generate one temp table for comma separated id and apply condition in the your query.
Like:-
DECLARE #variables VARCHAR(200) = #searchterm -- Your Variable
CREATE TABLE #temp(ID NUMERIC) DECLARE #temp VARCHAR(200)
SET #temp = #variables WHILE LEN(#temp) > 0 BEGIN DECLARE #t1 VARCHAR(200)
IF CHARINDEX(',',#temp) > 0
BEGIN
SET #t1 = SUBSTRING(#temp,0,CHARINDEX(',',#temp))
INSERT INTO #TEMP SELECT #t1
SET #temp = SUBSTRING(#temp,CHARINDEX(',',#temp)+1,len(#temp))
END
ELSE
BEGIN
INSERT INTO #TEMP SELECT #temp
SET #temp = ''
END
END
SELECT [ID]
,[NAME]
FROM [DataBase].[dbo].[tbl_Namelist]
WHERE ID IN (SELECT ID FROM #temp)

You can use the built-in function SPLIT_STRING function:
SELECT [ID], [NAME]
FROM [DataBase].[dbo].[tbl_Namelist]
WHERE ID IN (SELECT VALUE FROM SPLIT_STRING(#searchterm,','))
This only works on Compatibility level 130 or greater.
If you are on an older version of SQL Server you can follow this answer, which defines an equivalent function:
SELECT [ID], [NAME]
FROM [DataBase].[dbo].[tbl_Namelist]
WHERE ID IN (SELECT VALUE FROM fn_split_string(#searchterm,','))

Related

How to simplify batched SQL Inserts with too many parameters

So I am trying to insert data that looks like this:
INSERT INTO RELATIONSHIP_CONFIG (USERID, WORKGROUPID, PRIORITY) VALUES
(#userId, #WorkgroupId10, #SmartFeedPriority10),
(#userId, #WorkgroupId11, #SmartFeedPriority11),
(#userId, #WorkgroupId12, #SmartFeedPriority12),
(#userId, #WorkgroupId13, #SmartFeedPriority13);
Which generally is very simple and linear as all inserts happen one after the other and performs fine (I think).
The issue is that there is a hard limit with the number of SQL Parameters I am allowed to use- 2100.
The upper limit edge case accounts for an insert that is quite a bit above that.
I was thinking about passing the data for WorkgroupId and SmartFeedPriority as a csvs and using a split function to create tables or something like that...
What is the best approach for dealing with data like this?
Maybe creating a stored procedure, passing the #UserId, #WorkgroupId (CSV), and #SmartFeedPriority (CSV) and having linear, one by one inserts done this way, but I am not too sure how the logic for this will look...
Looking at your question it's a bit difficult to suggest a good approach. I'm unable to see how and where the source of the data is.
I see you mentioned a CSV file. You can import data from a CSV file using the below script. Once the data is in a table, you can try one of the below examples.
IF OBJECT_ID('tempdb.dbo.#TempTable', 'U') IS NOT NULL
DROP TABLE #TempTable ;
CREATE TABLE #TempTable
(
[UserID] NVARCHAR(MAX) NULL,
[WorkGroup] NVARCHAR(MAX) NULL,
[SmartFeedPriority] NVARCHAR(MAX) NULL,
)
BULK INSERT #TempTable
FROM ' put your csv file path here '
WITH
(
FIELDTERMINATOR = ',', -- comma delimited
ROWTERMINATOR = '\n',
CODEPAGE = 65001 --'65001'
)
If the data you're trying to insert is from a table, you could try selecting the data into the table you need it to be.
Example :
SELECT [UserID], [WorkgroupID], [SmartFeedPriority]
INTO [dbo].[RELATIONSHIP_CONFIG]
FROM [dbo].[SorceTable]
If you would like to take the procedural route you can try the below. The below sample would work if the source of your data is in a table and you would like to individually insert each record.
Example :
procedure for insert
CREATE PROCEDURE [dbo].[CREATE_RELATIONSHIP_CONFIG](#UserId INT, #WorkgroupId INT, #SmartFeedPriority INT)
AS
BEGIN
INSERT INTO RELATIONSHIP_CONFIG (UserId, WorkgroupId, Priority) VALUES
(#userId, #WorkgroupId, #SmartFeedPriority)
END
You can wrap the above procedure in a while loop.
I've added a example for it below.
declare #UserId int;
declare #WorkgroupId int;
declare #Priority int;
WHILE EXISTS (SELECT [UserID] FROM #TempTable)
BEGIN
SELECT TOP 1 #UserId=[UserID], #WorkgroupId=[WorkGroup] , #Priority=[SmartFeedPriority] FROM #TempTable
EXEC [dbo].[CREATE_RELATIONSHIP_CONFIG] #UserId, #WorkgroupId, #Priority
DELETE TOP (1)FROM #TempTable
END

Adding column to temporary table with select statments

I have a stored procedure I'm trying to create to fill a temporary table. But I need to make several passes at adding data based upon some conditions and capture those conditions with an additional field added to the temp table.
I start out like this:
select top 0
into #mytable
from UserTable
This I have found simply copies the basic structure with the same columns and types. Then I need to add a field:
alter table #mytable ADD reasontype varchar
The I make several passes at examining the table, here is one of them:
insert into #mytable
select distinct a.*, 'Annual'
from UserTable a
where (a.EnrollmentDate < DATEADD(year, -1, getdate())
This is to select those that require an annual review. The procedure compiles without an error but when I try to fill a datatable I get the error that string or binary data would be truncated. What am I doing wrong?
alter table #mytable ADD reasontype varchar(max)
If that works, either use "max" or a value that won't truncate your values...or use a LEFT statement where the length matches the longest value of reasontype
example for left:
alter table #mytable ADD reasontype varchar(3)
insert into #mytable
select distinct a.*, LEFT('Annual',3)
from UserTable a
where (a.EnrollmentDate < DATEADD(year, -1, getdate())
but you probably just want this:
alter table #mytable ADD reasontype varchar(6) /* where 6 is the length of the string "Annual" */
Use a length on your varchar, 'Annual' is being truncated to 'A'. If you're planning on indexing the reasontype field, don't use varchar(max), it exceeds the maximum width of an indexable field

How to insert values using Joins in asp.net stored procedure?

CREATE PROCEDURE [dbo].[K_HRM_Insert_VehicleAssign]
#vehiclename varchar(50),
#empname varchar(50),
#updatedby varchar(50),
#updatedon datetime
AS
BEGIN
INSERT INTO K_MasterEmpDetails ME
INNER JOIN K_HRM_Vehicle_Assign VA ON VA.[empname+id] = ME.Firstname +' '+ME.Lastname + ' - ' + ME.kjlid AS ME.Employee
(VA.vehiclename, ME.Employee, VA.updatedby, VA.updatedon)
VALUES (#vehiclename, #empname, #updatedby, GETDATE())
END
I am getting an error near ME...please help me
You can't use this syntax. Correct syntax is:
INSERT INTO Table
(COLUMNS)
VALUES
(value)
For correct insert into two tables you have to use transaction and insert into two table separately.
You're syntactically wrong. The correct syntax is what user said is basic
but you can use
Insert into Table
select statement
It will select the rows based on condition then insert into table.
and in select statement you can use join.

Insert and select in different queries SQL

I have a server and many clients, my application is on clients and database on server, i have one table
Table --> Id --> int Auto-increment,
Name --> nvarchar(50),
So, whenever i insert a new row from client with query
Insert into Table Name Values('NameValue')
It inserts the row and sql auto generates the Id field. So, to fetch its Id, I use the following query
Select max(Id) as maxId from Table
but both queries are on different connections
It works well when only one client is operating at a time, but when multiple clients are working, Many insert queries are requested by clients before i could request the 'getMaxId' query.
You can use the following:
SELECT SCOPE_IDENTITY()
This selects the last-inserted identity.
The best way is to run a command to get the recent inserted value.
There are three commands you can run to do that.
This link will explain them
the best is
SELECT SCOPE_IDENTITY()
because if you have a table A that calls a trigger and this trigger inserts data on a table B, this command will get you the ID of the table A, while ##IDENTITY will get you the id of table B
Try this:
DECLARE #a TABLE (
Id int IDENTITY (1, 1),
b VARCHAR(1000)
)
DECLARE #b TABLE (
Id INT
)
INSERT #a (b)
OUTPUT INSERTED.Id INTO #b
SELECT NAME
FROM sys.objects
SELECT * FROM #a
SELECT * FROM #b
Or, you can always use that for retrieving the latest ident:
SELECT IDENT_CURRENT('TABLE_NAME')
Or use
SELECT SCOPE_IDENTITY()
Rather use:
select ##identity
instead of select max(id)...
It will return the last generated identity for the current connection.
use this, but it works for PHP
$id = mysql_insert_id();
and for c#
Int32 newId = (Int32) myCommand.ExecuteScalar();
Add the following after inserting instead of Max(id) selection.
SELECT SCOPE_IDENTITY()
Make function in sql, where you will add row and get ID by SELECT SCOPE_IDENTITY(). While you call function you will get ID which is exactly added.
try this hope it will may help You
declare #table1 table(id int identity,name varchar(50))
insert into #table1 (name) output inserted.id values('abc')
insert into #table1 (name) output inserted.id values('xyz')
insert into #table1 (name) output inserted.id values('pqr')
for more see here

Problem in stored procedure

create procedure InsertQuestionEntry
#round_name varchar(40),
#question varchar(100),
#answer varchar(40),
#option1 varchar(20),
#option2 varchar(30),
#option3 varchar(30)
as
begin
insert into QuestionEntry(Question,Round_Name) values(#question,#round_name);
declare #quesion_id int
exec #quesion_id= select Question_ID from QuestionEntry;
insert into Answer(Question_ID,Answer,Option1,Option2,Option3) values(#quesion_id,#answer,#option1,#option2,#option3);
end
Here I want to retrieve the Question_ID from table QuestionEntry and use that Question_ID to another table Answer
But this didn't work.
So how can I use above way?
please help me
Instead of
insert into QuestionEntry(Question,Round_Name) values(#question,#round_name);
declare #quesion_id int
exec #quesion_id= select Question_ID from QuestionEntry;
use the following:
DECLARE #quesion_id int
INSERT INTO QuestionEntry(Question,Round_Name) values(#question,#round_name)
SET #quesion_id = SCOPE_IDENTITY()
You should not use "exec" there.
What exec does is:
Executes a command string or character
string within a Transact-SQL batch, or
one of the following modules: system
stored procedure, user-defined stored
procedure, scalar-valued user-defined
function, or extended stored
procedure.
You should use "set" or "select" instead of exec.
SET can only assign one variable at
a time, SELECT can make multiple
assignments at once. When assigning
from a query if there is no value
returned then SET will assign
NULL, where SELECT will not make
the assignment at all (so the variable
will not be changed from it's previous
value)
You can find more info about when to use SET or SELECT here: SET vs SELECT when assigning variables
Sample:
set #quesion_id = (select Question_ID from QuestionEntry)
select #quesion_id = (select Question_ID from QuestionEntry)
But that's also wrong way to get identity value from inserted record. If you have N users execute a same procedure at a same time it can happen that you will get wrong value (from last inserted record).
To do this properly you should use ##IDENTITY or even better SCOPE_IDENTITY(). More info: here.
After INSERT you can simply call:
SELECT #quesion_id = ##IDENTITY
--or
SELECT #quesion_id = SCOPE_IDENTITY()
Also, check your Question_ID is configured properly. It should be set to auto increment.
Sample:
Question_ID int IDENTITY(1,1)PRIMARY KEY CLUSTERED
The 1's following the IDENTITY keyword indicate the SEED number (value for first record in table) and increment property (0 or 1).
If your server's version is SQL Server 2005 or higher, you could also try something like this:
create procedure InsertQuestionEntry
#round_name varchar(40),
#question varchar(100),
#answer varchar(40),
#option1 varchar(20),
#option2 varchar(30),
#option3 varchar(30)
as
begin
insert into QuestionEntry(Question,Round_Name)
output inserted.Question_ID, #answer, #option1, #option2, #option3
into Answer (Question_ID, Answer, Option1, Option2, Option3)
values(#question,#round_name);
end

Categories