Getting rid of duplicated data in a GridView - c#

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

Related

How to fix the " The multi-part identifier "word" could not be bound" error

I want to insert some datas from a notepad, but i got this error:"The multi-part identifier "id.localitate" could not be bound."
Here is the code:
string[] siruri = sir.Split(split);
cmd = new SqlCommand("Insert into Localitati(nume) values(#localitate)", con);
cmd.Parameters.AddWithValue("localitate", siruri[0].Trim());
cmd.ExecuteNonQuery();
cmd = new SqlCommand("Select id.localitate from Localitati where nume=#nume", con);
cmd.Parameters.AddWithValue("nume", siruri[0].Trim());
int idlocalitate = Convert.ToInt32(cmd.ExecuteScalar());
int nrzile;
As per your command id.localitate is a column on a tabel called Localitati, you need to use the column name with square brackets as [id.localitate], so the code will be:
cmd = new SqlCommand("Select [id.localitate] from Localitati where nume=#nume", con);
Yes, cause there is no such table alias defined in your query. It should be then like
Select id.localitate from Localitati id where nume=#nume
Or just the query without any table alias
Select localitate from Localitati where nume=#nume
per your comment id.localitate is a column on a tabel called Localitate
You need to escape the column then using [] like Select [id.localitate] or Select "id.localitate" though I would never recommend having a column with such name. Define your DB objects name (Table, Column) properly
Let's say you got a Table "Localitati" like this:
| Id | Name | FatherId |
| 1 | A | null |
| 2 | B | 1 |
You could run a Select like this:
SELECT Id FROM Localitati WHERE 1 = 1;
In your query you can set synonyms for your tables to select the corret column. This is needed if you want to join to the table itself:
SELECT a.Id, b.Id
FROM Localitati a
LEFT JOIN Localitati b
ON a.Id = b.FatherId
WHERE 1 = 1;
Your question said, that your columns name is "id.Localitati" (which id don't think). If this is the case, you have to quote your column-name:
| Id.Localitati | Name | FatherId |
| 1 | A | null |
| 2 | B | 1 |
The query would look like this:
SELECT a."Id.Localitati", b."Id.Localitati"
FROM Localitati a
LEFT JOIN Localitati b
ON a."Id.Localitati" = b.FatherId
WHERE 1 = 1;
But you shouldn't use dots in any names..

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.

Error mapping data type Oracle and C#

I have an table with ID NUMBER(18) and I have a class with properties public Int64 ID { get; set; } to mapping ID form C# vs Oracle.
My table definition
But I have an error when I get max ID like this:
Run query
SELECT MAX(ID) ID FROM MYTABLE
The system throw an error:
"Object of type 'System.Decimal' cannot be converted to type 'System.Int64'."
But when I run query like this:
SELECT ID FROM(
SELECT ID FROM MYTABLE ORDER BY ID DESC
) WHERE ROWNUM =1
It OK.
I don't know why (1) throw error, and why (2) done?
What is the difference between datatype (1) and (2)?
Possible scenario 1:
I guess that you have NULL values in table (so your both queries are not equivalent):
SELECT MAX(ID) ID FROM T_00_RQMM -- aggregate func ignore NULLS
But:
SELECT ID FROM(SELECT ID FROM T_00_RQMM ORDER BY ID DESC) WHERE ROWNUM = 1;
-- NULL is the max value
DBFiddle Demo
Anyway you should try mapping:
using System.Numerics;
...
public BigInteger ID { get; set; }
EDIT:
Possible scenario 2:
It may be problem with data type (then use explicit CAST):
SELECT CAST(MAX(ID) AS NUMBER(18,0)) ID FROM T_00_RQMM
DBFiddle Demo 2
Full demo:
CREATE TABLE T_00_RQMM (ID NUMBER(18,0));
INSERT INTO T_00_RQMM VALUES(NULL);
INSERT INTO T_00_RQMM VALUES(100);
CREATE TABLE t1 AS SELECT MAX(ID) ID FROM T_00_RQMM;
CREATE TABLE t2 AS SELECT ID FROM(SELECT ID FROM T_00_RQMM ORDER BY ID DESC)
WHERE ROWNUM = 1;
CREATE TABLE t3 AS SELECT CAST(MAX(ID) AS NUMBER(18,0)) ID FROM T_00_RQMM;
SELECT TABLE_NAME, COLUMN_NAME, DATA_PRECISION, DATA_SCALE
FROM all_tab_cols
where table_name in ('T1', 'T2', 'T3')
ORDER BY Table_name;
Output:
+------------+-------------+----------------+------------+
| TABLE_NAME | COLUMN_NAME | DATA_PRECISION | DATA_SCALE |
+------------+-------------+----------------+------------+
| T1 | ID | null | null |
| T2 | ID | 18 | 0 |
| T3 | ID | 18 | 0 |
+------------+-------------+----------------+------------+

C# Nested Loop for inserting multiples into DB

I have an application used for warehousing furniture. If the user enters a line with a qty > 1, I have a simple while loop where the line is broken out to be many unique lines inserted into a SQL db. I.e.
Item chair Qty 3
Becomes
Item |Qty|Unique Key
Chair |1 |1234
Chair |1 |1235
Chair |1 |1236
--
while (Qty >= 1)
{
//Go Get Next Num
// GetNextNum("LN");
int NextNum = GetNextNum("LN"); //Method to get next number from DB table
SqlConnection conn = new SqlConnection();
SqlCommand cmd = new SqlCommand();
string connStr = ConfigurationManager.ConnectionStrings["FurnitureDB"].ConnectionString;
conn.ConnectionString = connStr;
conn.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
//SQL Parameter List here
cmd.CommandText = "InsertSODtl";
SqlDataReader datareader = cmd.ExecuteReader();
Qty--;
}
My challenge is, there are some items that have a multiplier, where one item will be in 3 pieces. In which case I append a number behind the unique key:
Item Table - Qty 1 - Unique Key
------------------------------------
Table | 1 | 1234
Table | 1 | 12341
Table | 1 | 12342
So I need a nested while loop/for loop or some method to insert the appropriate number of pieces. So a table for example - there could be 2 tables, each with 3 pieces. So I need to
Item Table - Qty 1 - Unique Key
------------------------------------
Table | 1 | 1234
Table | 1 | 12341
Table | 1 | 12342
Table | 1 | 1235
Table | 1 | 12351
Table | 1 | 12352
I'm struggling to come up with the logic to do this correctly.
Thanks for your suggestions.
One option I would look at is doing this all from within the stored procedure to limit the queries you need to execute. This can be really easily achieved using any type of for loop in SQL. Now i have a basic table setup as below.
ItemTable
Item | nvarchar(50)
Qty | int
UniqueKey | int
ItemClassification
Item | nvarchar(50)
NumberOfPieces | int
Then a simple stored procedure such as:
CREATE PROCEDURE [dbo].[InsertSODtl]
#item nvarchar(50),
#uniqueKey int
AS
BEGIN
SET NOCOUNT ON
DECLARE #pieces int = (SELECT TOP 1 NumberOfPieces FROM ItemClassification WHERE Item = #item)
INSERT INTO ItemTable (Item, Quantity, UniqueKey) VALUES (#item, 1, #uniqueKey)
IF #pieces IS NOT NULL AND #pieces > 1
BEGIN
DECLARE #count int = 1;
WHILE #count < #pieces -- < assures we end -1 max piece count
BEGIN
INSERT INTO ItemTable VALUES (#item, 1, CAST(CAST(#uniqueKey as nvarchar(10)) + CAST(#count as nvarchar(5)) as int))
SET #count = #count + 1
END
END
END
Like I said it is pretty basic and probably not exactly how your tables look but the concept is there.
First query the amount of pieces in the ItemClassification table for the Item type (simple string).
Next insert the record into the ItemTable
Finally if #pieces is not null and #pieces > 1 then we run a loop from 1 to #pieces - 1 inserting back into the ItemTable appending the value to the unique key. Now we have to cast the #uniqueKey and #count as string (nvarchar(10)) as we need to concat the values and not add them together.
Again a pretty basic example but limits the required queries.
This also doesnt require a change to your code and can be done in one query.
Example Use:
EXEC InsertSODtl 'Table', 1234
EXEC InsertSODtl 'Table', 1235
EXEC InsertSODtl 'Chair', 1236
Results in:

join self-reference table

I have following self-reference table
Name | Id |CategoryId
--------------------------------
Gruop1 | 1 |null
--------------------------------
Group2 | 2 | 1
--------------------------------
Group3 | 3 | 1
--------------------------------
Id=int AtuoNumber
CategoryId=int nullable
I need query that its result is like this (linq to sql or sql command)
Name | Id | CategoryId | CategoryName
---------------------------------------------------------
Gruop1 | 1 | null | null
---------------------------------------------------------
Group2 | 2 | 1 | Group1
---------------------------------------------------------
Group3 | 3 | 1 | Group1
---------------------------------------------------------
I tried this code but it didn't work properly
SELECT *
FROM Category e1
inner join Category e2
ON e1.Id = e2.CategoryId
Any idea?
SELECT e1.name,e1.id,e1.categoryid,e2.name as categoryname
FROM Category e1
left join Category e2
ON e2.id = e1.CategoryId
I am guessing that you are missing the null valued rows (where CategoryId is null). This is because in any RDBMS any comparison to NULL always returns false, even of you compare null to null.
To get what you want, I believe you need a UNION query, with the second part of the union selecting rows where CategoryId is null
SELECT e1.Name , e1.Id , e1.CategoryId, e2.Name as CategoryName
FROM Category AS e1 INNER JOIN Category AS e2 ON e1.id = e2.CategoryId
union
SELECT e1.Name , e1.Id , e1.CategoryId,null as CategoryName
FROM Category e1 where CategoryId is null
This will do the job for you.
declare #temp table
(
[Id] [int] IDENTITY(1,1),
[CategoryId] [int] NULL ,
Name varchar(20)
)
insert into #temp(CategoryId, Name)
values
(null,'Group1'),
(1,'Group2'),
(1,'Group3')
select t1.Name,t1.Id,t1.CategoryId,t2.Name
from #temp t1
left outer join #temp t2 on t1.CategoryId = t2.Id

Categories

Resources