C# SQL Query Producing Different Results than Management Studio - c#

SELECT
wl.WatchListId, wl.Code, wl.[Description], wl.DateCreated,
wl.CreatedBy, wl.DateModified, wl.ModifiedBy,
wpi.ParameterExpression as IndividualExpression,
wpb.ParameterExpression as BusinessExpression,
wpd.ParameterExpression as DefaultExpression,
CASE
WHEN EXISTS(SELECT 1 FROM SourceWatchList
WHERE SourceId = #SourceId AND WatchListId = wl.WatchListId)
THEN 1 ELSE 0
END AS IsActive
FROM
[WatchList] wl
LEFT JOIN
SourceWatchList swl ON wl.WatchListId = swl.WatchListId AND swl.SourceId = #SourceId
LEFT JOIN
(SELECT
ParameterExpression, SourceId, WatchListId
FROM WatchListParameter
WHERE EntityType = 'INDIVIDUAL') wpi ON wpi.SourceId = #SourceId
AND wpi.WatchListId = wl.WatchListId
LEFT JOIN
(SELECT
ParameterExpression, SourceId, WatchListId
FROM WatchListParameter
WHERE EntityType = 'BUSINESS') wpb ON wpb.SourceId = #SourceId
AND wpb.WatchListId = wl.WatchListId
LEFT JOIN
(SELECT ParameterExpression, SourceId, WatchListId
FROM WatchListParameter
WHERE EntityType = 'DEFAULT') wpd ON wpd.SourceId = #SourceId
AND wpd.WatchListId = wl.WatchListId
WHERE
wl.IsActive = 1
I have the above query. Pretty simple.
Here's a snippet from SQL Server Management Studio table :
and from the debugger in Visual Studio :
The Visual Studio table has no data in the 3 Expression Columns while the Management Studio (correctly) does. Can any tell me why that is, and what steps I can take to resolve the issue?
I'm 100% sure I've used the same parameter between the two as well.
string sql = #"SELECT wl.WatchListId,wl.Code,wl.[Description],wl.DateCreated,
wl.CreatedBy,wl.DateModified,wl.ModifiedBy,
wpi.ParameterExpression as IndividualExpression,
wpb.ParameterExpression as BusinessExpression,
wpd.ParameterExpression as DefaultExpression,
CASE WHEN EXISTS(Select 1 FROM SourceWatchList
WHERE SourceId = #SourceId AND WatchListId = wl.WatchListId)
THEN 1 ELSE 0 END AS IsActive
FROM [WatchList] wl
LEFT JOIN SourceWatchList swl on wl.WatchListId = swl.WatchListId and swl.SourceId = #SourceId
LEFT JOIN (Select ParameterExpression, SourceId, WatchListId FROM WatchListParameter WHERE EntityType = 'INDIVIDUAL') wpi
ON wpi.SourceId = #SourceId AND wpi.WatchListId = wl.WatchListId
LEFT JOIN (Select ParameterExpression, SourceId, WatchListId FROM WatchListParameter WHERE EntityType = 'BUSINESS') wpb
ON wpb.SourceId = #SourceId AND wpb.WatchListId = wl.WatchListId
LEFT JOIN (Select ParameterExpression, SourceId, WatchListId FROM WatchListParameter WHERE EntityType = 'DEFAULT') wpd
ON wpd.SourceId = #SourceId AND wpd.WatchListId = wl.WatchListId
where wl.IsActive = 1";
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["WatchListCompliance"].ConnectionString);
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("#SourceId", SourceId);
DataTable dt = new DataTable();
using (SqlDataAdapter a = new SqlDataAdapter(cmd))
{
a.Fill(dt);
}

This might be a problem with types and equality. You can try using SqlDataType when you define the parameters on the sqlcommand. When you use addwithvalue without declaring a type it could be selecting the wrong type. Then you should use the type you declared in the sql expression.
cmd.Parameters.Add("#SourceId", SqlDbType.VarChar, 20);
cmd.Parameters["#SourceId"].Value = SourceId;

Wild guess: are you sure your session is configured the same way? Especially the SET ANSI_NULLS option, which changes how comparison behaves with regard to null values.
It is worth noting that some databases may have unusual default values, but some clients (e.g. ADO.NET) explicitely define their own values for the session when they connect, even if you don't ask them to.

Related

Select Query Parameter from C# in a stored procedure

How does a SQL Server query select from parameter? I just want to make it simple set select column based on my C# code. Is it possible?
Here is my stored procedure:
ALTER PROCEDURE [dbo].[GetMembersDetailGenerateChanceTop10000]
#EventId nvarchar(255),
#PeriodId nvarchar(255),
#QueryParam nvarchar(1000)
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT TOP 10000 #QueryParam
FROM ign..Chance_Generated cg
INNER JOIN ign..Contact c ON cg.ContactID = c.ContactId
LEFT JOIN ign..CustomerAddress ca ON ca.parentid = cg.contactid
LEFT JOIN ign..new_cardlevelconfig cl ON cl.new_cardlevelconfigid = c.new_cardlevel
LEFT JOIN ign..new_country co ON co.new_countryid = c.new_country
LEFT JOIN ign..new_province po ON po.new_provinceId = c.new_Province
LEFT JOIN ign..StringMap sm ON sm.AttributeValue = c.new_IDType
LEFT JOIN ign..new_city cy ON cy.new_cityId = c.new_CityCounty
LEFT JOIN ign..new_transactionheader th ON cg.New_Name COLLATE DATABASE_DEFAULT = th.new_name COLLATE DATABASE_DEFAULT
WHERE cg.EventId = #EventId
AND (ca.AddressNumber = '1' OR ca.AddressNumber IS NULL)
AND (sm.AttributeName IS NULL OR sm.AttributeName = 'new_idtype')
AND cg.periodId = #PeriodId
QueryParam, EventId, PeriodId will be filled from C# code.
Here is my C# code:
private List<GenerateModel> getDataTopFromStoreProcedure(string EventId, string PeriodId)
{
// query select parameter
string QueryParam = #"cg.Chance_Number, th.new_name as [th name], dateadd(HOUR,7,th.createdon) as [th createdon],
c.new_Initial, c.FirstName, c.LastName";
string ConnString = GenerateChance.Properties.Settings.Default["DB_ConnectionString"].ToString();
using (SqlConnection conn = new SqlConnection(ConnString))
{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = GetMembersDetailGenerateChanceTop10000;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 0; //no limit
cmd.Parameters.Clear();
cmd.Parameters.Add(new SqlParameter("QueryParam", QueryParam));
cmd.Parameters.Add(new SqlParameter("EventId", EventId));
cmd.Parameters.Add(new SqlParameter("PeriodId", PeriodId));
cmd.Connection = conn;
if (conn.State == ConnectionState.Open)
conn.Close();
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
list.Add(new GenerateModel
{
ChanceNumber = reader["Chance_Number"].ToString(), //System.IndexOutOfRangeException Error
Receipt = reader["th name"].ToString(),
Date = reader["th createdon"].ToString(),
Initial = reader["new_Initial"].ToString(),
FirstName = reader["FirstName"].ToString(),
LastName = reader["LastName"].ToString(),
});
}
reader.Close();
}
}
return list;
}
I am confused as to how to implement his method because I want to get return of all select results in object model but I always get error
System.IndexOutOfRangeException : Chance_Number.
Honestly why do I use query select parameter is because I want to get value from checkedListBox1 that already I defined before by using this code get all checkedListBox1 value to determine select query.
string QueryParam = "cg.Chance_Number";//auto get chance_number as select mandatory
for (int i = 0; i < checkedListBox1.CheckedItems.Count; i++)
{
QueryParam += ", " + ((clsItemList)checkedListBox1.CheckedItems[i]).Value;
}
You have to use constructor with proper length for parameters as given below, to avoid the issue.Read more on SQLParameter
public SqlParameter (string parameterName, System.Data.SqlDbType dbType, int size);
cmd.Parameters.Add(new SqlParameter("QueryParam", SqlDbType.NVarChar,1000)).Value = QueryParam;
You need to make few more changes:
The way you have defined the procedure is wrong. You have to define the procedure as dynamic sql for the #queryparam to get concatenated to the SELECT query as given below:
DECLARE #selectStmt NVARCHAR(MAX) = ''
DECLARE #sqldefinition NVARCHAR(4000) = '#EventId nvarchar(255), #PeriodId nvarchar(255)'
SET #selectStmt += 'select distinct top 10000 ' + #QueryParam +
'from ign..Chance_Generated cg
inner join ign..Contact c on cg.ContactID = c.ContactId
left join ign..CustomerAddress ca on ca.parentid = cg.contactid
left join ign..new_cardlevelconfig cl on cl.new_cardlevelconfigid = c.new_cardlevel
left join ign..new_country co on co.new_countryid = c.new_country
left join ign..new_province po on po.new_provinceId = c.new_Province
left join ign..StringMap sm on sm.AttributeValue = c.new_IDType
left join ign..new_city cy on cy.new_cityId = c.new_CityCounty
left join ign..new_transactionheader th on cg.New_Name COLLATE DATABASE_DEFAULT = th.new_name COLLATE DATABASE_DEFAULT
where cg.EventId= '''+ #EventId +''' and (ca.AddressNumber = ''1'' or ca.AddressNumber is null) and (sm.AttributeName is null or sm.AttributeName = ''new_idtype'')
and cg.periodId = ''' + #PeriodId + ''';'
EXEC #sp_executesql #selectStmt, #sqldefinition, #EventId , #PeriodId
``
- Always refer the tables with proper schema in the query
ign.SchemaName.new_country
ign.SchemaName.new_province

Correct query not working using MySqlDataReader

So I'm trying to figure out of this, in particular I have this query that perfectly works using PhpMyAdmin:
SELECT tt.team_id, (CASE WHEN t.id IS NULL THEN 0 ELSE 1 END) as exist FROM(SELECT 13048 as team_id UNION ALL SELECT 17058 UNION ALL SELECT 38809 UNION ALL SELECT 8216 UNION ALL SELECT 5466) tt LEFT JOIN team t on t.id = tt.team_id WHERE t.id IS NULL OR t.update_at < DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
Anyway, I get this error from Visual Studio:
MySql.Data.MySqlClient.MySqlException: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' UNION ALL SELECT 17058 UNION ALL SELECT 38809 UNION ALL SELECT 8216 UNION ALL ' at line 1'
This error is retured on:
using (MySqlDataReader reader = command.ExecuteReader())
I setup the query in this way:
command.CommandText = "SELECT tt.team_id, " +
"(CASE WHEN t.id IS NULL THEN 0 ELSE 1 END) as exist " +
"FROM(SELECT #first as team_id #others) tt LEFT JOIN team t on t.id = tt.team_id " +
"WHERE t.id IS NULL OR " +
"t.update_at < DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)";
command.Parameters.Add("#first", MySqlDbType.Int32).Value = teams.First().Id;
command.Parameters.Add("#others", MySqlDbType.String).Value = string.Concat(teams.Skip(1).Select(c => " UNION ALL SELECT " + c.Id));
Someone could help me?
This is how I would build a dynamic list of parameters to pass to your query.
Warning, not tested, but this should produce the expected output
// Command text with a placeholder where we insert the dynamic text
string cmd = #"SELECT tt.team_id,
(CASE WHEN t.id IS NULL THEN 0 ELSE 1 END) as exist
FROM (SELECT {texttoreplace}) tt
LEFT JOIN team t on t.id = tt.team_id WHERE t.id IS NULL
OR t.update_at < DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)";
int prmCounter = 1;
// Where we keep the text to insert at the appropriate place
StringBuilder unions = new StringBuilder();
// Where we keep the parameters to add at the MySqlCommand
List<MySqlParameter> prms = new List<MySqlParameter>();
// First parameter
MySqlParameter pr = new MySqlParameter("#first", MySqlDbType.Int32) { Value = teams.First().id};
prms.Add(pr);
unions.Append($" #first as team_id ");
// Loop over your IDs and build parameters and text
foreach (var t in teams.Skip(1))
{
// Giving an unique name to the parameter
string placeholder = "#p" + prmCounter;
unions.Append($" UNION ALL SELECT {placeholder}");
pr = new MySqlParameter(placeholder, MySqlDbType.Int32) { Value = t.id};
prms.Add(pr);
prmCounter++;
}
// Add all the required parameters
command.Parameters.AddRange(prms.ToArray());
// Replace the placeholder with the built text
cmd = cmd.Replace("{texttoreplace}", unions.ToString());

sql command yields empty results that aren't empty in sql server

So, I'm trying to build a code generator that will extract indexes from a database and make a class that will filter based on an index.
Below code works in SQL-server and yields 2 records. But my SqlDataReader yields zero records.
Provided example for 1 table with index.
Hoping someone can help me out here.
Code in SQL server:
create table Agent(
ID bigint constraint PK_Agent primary key identity(1,1),
LastName nvarchar(50) not null,
FirstName nvarchar(50) not null,
index IN_Agent_Name nonclustered (LastName, FirstName)
)
select t.object_id,
s.name as schemaname,
t.name as tablename,
i.index_id,
i.name as indexname,
index_column_id,
c.name as columnname
from sys.tables t
inner join sys.schemas s on t.schema_id = s.schema_id
inner join sys.indexes i on i.object_id = t.object_id
inner join sys.index_columns ic on ic.object_id = t.object_id and ic.index_id = i.index_id
inner join sys.columns c on c.object_id = t.object_id and ic.column_id = c.column_id
where i.index_id > 0
and i.type in (1, 2)
and i.is_primary_key = 0
and i.is_unique_constraint = 0
and i.is_disabled = 0
and i.is_hypothetical = 0
and ic.key_ordinal > 0
and t.name like 'Agent'
and i.name like 'IN_Agent_Name'
Code in VS:
public static TableIndex GetIndex(string indexName, string tableName)
{
TableIndex index = null;
using (var conn = new SqlConnection("Server=localhost;Database=VenturaERD;User Id=VenturaDBUser;Password = Ventura;"))
{
conn.Open();
var cmd = new SqlCommand("select t.object_id, s.name as schemaname, t.name as tablename, i.index_id, i.name as indexname, index_column_id, c.name as columnname from sys.tables t inner join sys.schemas s on t.schema_id = s.schema_id inner join sys.indexes i on i.object_id = t.object_id inner join sys.index_columns ic on ic.object_id = t.object_id and ic.index_id = i.index_id inner join sys.columns c on c.object_id = t.object_id and ic.column_id = c.column_id where i.index_id > 0 and i.type in (1, 2) and i.is_primary_key = 0 and i.is_unique_constraint = 0 and i.is_disabled = 0 and i.is_hypothetical = 0 and ic.key_ordinal > 0 and t.name like '" + tableName + "' and i.name like '" + indexName + "'")
{
Connection = conn
};
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
index = new TableIndex()
{
TableId = reader.GetInt32(reader.GetOrdinal("object_id")),
TableName = reader.GetString(reader.GetOrdinal("tablename")),
IndexId = reader.GetInt32(reader.GetOrdinal("index_id")),
IndexName = reader.GetString(reader.GetOrdinal("indexname")),
Columns = new List()
{
new IndexColumn()
{
ColumnName = reader.GetString(reader.GetOrdinal("columnname")),
Order=reader.GetInt32(reader.GetOrdinal("index_column_id"))
}
}
};
while (reader.Read())
{
index.Columns.Add(new IndexColumn()
{
ColumnName = reader.GetString(reader.GetOrdinal("columnname")),
Order = reader.GetInt32(reader.GetOrdinal("index_column_id"))
});
}
}
reader.Close();
}
}
return index;
}
Please check the users rights, I believe with only the public rights the user will not get any data.
Make sure the user you are connecting to with SQL management studio and the user in the connection string are the same.
The user (in my tests at least) needs at least the db_datareader role.

Syntax for inner Join query for 4 table

I want to get the data from my access database and show the data at Datagridview. my tables are:
TABLE 1(AB) TABLE 2(CD) TABLE 3(EF) TABLE 4(GH)
------------- ----------------- ------------- -------------------
SID SName CID TID TID TName Tprice FID CID FCp FPID FID FCp Fprice
The query which I am using to retrieve the data in C# is:
OleDbCommand command1 = new OleDbCommand();
command1.Connection = connection;
command1.CommandText = "select T.TName, T.Tprice, P.FCp, P.Fprice from (([AB] S inner join [CD] T on S.TID = T.TID) (inner join [EF] C on S.CID = C.CID) inner join [GH] P on C.FID = P.FID where (S.SID = 2) ";
OleDbDataReader myreader = command1.ExecuteReader();
while (myreader.Read())
{
//DATA IS READ HERE
}
The error which I am getting is:
Syntax error at JOIN expression
I want TName, Tprice, FCp(TABLE 4), Fprice as my output. Am I doing it right or is there any other way to do that.
In your from you have opening parentheses with no closing (the first one).
Besides fixing the parentheses it is much more readable if you jump lines:
command1.CommandText = #"select T.TName, T.Tprice, P.FCp, P.Fprice
from (([AB] S
inner join [CD] T on S.TID = T.TID)
inner join [EF] C on S.CID = C.CID)
inner join [GH] P on C.FID = P.FID
where S.SID = 2";
(Access requires parentheseses)

SQL 2008 - Foreign key constraints in the INFORMATION_SCHEMA view

I am writing a c# unit test that validates string properties for an ORM class against the target database, always SQL 2008, and the class that the data maps to.
Checking that a specified foreign key is valid in the DB is easy:
static private bool ConstraintExsits(string table, string column, ConstraintType constraintType)
{
string constraintTypeWhereClause;
switch (constraintType)
{
case ConstraintType.PrimaryKey:
constraintTypeWhereClause = "PRIMARY KEY";
break;
case ConstraintType.ForeignKey:
constraintTypeWhereClause = "FOREIGN KEY";
break;
default:
throw new ArgumentOutOfRangeException("constraintType");
}
var cmd = new SqlCommand(
#"SELECT a.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS a
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE b on a.CONSTRAINT_NAME = b.CONSTRAINT_NAME
WHERE a.TABLE_NAME = #table AND b.COLUMN_NAME = #column AND a.CONSTRAINT_TYPE = '" + constraintTypeWhereClause + "'",
Connection);
cmd.Parameters.AddWithValue("#table", table.Trim('[').Trim(']'));
cmd.Parameters.AddWithValue("#column", column.Trim('[').Trim(']'));
return !string.IsNullOrEmpty((string)cmd.ExecuteScalar());
}
Now take the following Foreign Key Relationships:
My question: How do I query the relationship from the 'Primary/Unique Key Base Table' and 'Primary/Unique Key Columns' side? I cannot see these referenced in the INFORMATION_SCHEMA views.
Thanks
J
This is the SQL that I was after!
SELECT
FK_Table = FK.TABLE_NAME,
FK_Column = CU.COLUMN_NAME,
PK_Table = PK.TABLE_NAME,
PK_Column = PT.COLUMN_NAME,
Constraint_Name = C.CONSTRAINT_NAME
FROM
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK
ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN
INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK
ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU
ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN
(
SELECT
i1.TABLE_NAME, i2.COLUMN_NAME
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2
ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
) PT
ON PT.TABLE_NAME = PK.TABLE_NAME
Jaimie's answer fails to correctly return all the foreign keys if the referred table (the table that the foreign key is looking against) has a unique key because it uses the UNIQUE_CONSTRAINT_NAME column. I suggest:
SELECT
FK = fk.name,
FKTable = QUOTENAME(OBJECT_SCHEMA_NAME(fkcol.[object_id]))
+ '.' + QUOTENAME(OBJECT_NAME(fkcol.[object_id])),
FKCol = fkcol.name,
' references => ',
PKTable = QUOTENAME(OBJECT_SCHEMA_NAME(pkcol.[object_id]))
+ '.' + QUOTENAME(OBJECT_NAME(pkcol.[object_id])),
PKCol = pkcol.name
FROM sys.foreign_keys AS fk
INNER JOIN sys.foreign_key_columns AS fkc
ON fk.[object_id] = fkc.constraint_object_id
INNER JOIN sys.columns AS fkcol
ON fkc.parent_object_id = fkcol.[object_id]
AND fkc.parent_column_id = fkcol.column_id
INNER JOIN sys.columns AS pkcol
ON fkc.referenced_object_id = pkcol.[object_id]
AND fkc.referenced_column_id = pkcol.column_id
ORDER BY fkc.constraint_column_id;
Source:
The case against INFORMATION_SCHEMA views

Categories

Resources