Get full name of SQL Server tables - c#

Just some extract from the code:
cmd.CommandText = "SELECT TABLE_TYPE, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES";
using (dataReader = cmd.ExecuteReader())
{
string tableName = (string)dataReader["TABLE_NAME"];
}
Should I use "table_schema" column of th INFORMATION_SCHEMA.TABLES like this:
dbo.string fullname = dataReader["table_schema"]+"."+dataReader["table_name"];
Or should I use another method? I need to insert this fullname in a script for insertion table data.

Try something like this:
SELECT
SchemaName = s.Name,
TableName = t.Name,
FullName = s.Name + '.' + t.Name
FROM
sys.tables t
INNER JOIN
sys.schemas s ON s.schema_id = t.schema_id
This should give you the schema, the table name, and the combined (schema).(table name) notation

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

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.

How to display the results of inner join query table in sqlite?

So, I'm using C# winrt with SQLite database. I want to display the results of the query which i have "join"ed.
I have 2 tables which are Student and Course.
Student has : id(PK), name, courseid
Course has : courseid(PK), coursename
And here is my code :
var query1 = conn.QueryAsync<Student>("select * from Student s inner Join Course c on s.courseid = c.courseid");
var query2 = conn.QueryAsync<Course>("select * from Course c inner join Student s on c.courseid = s.courseid");
var result1 = await query1;
var result2 = await query2;
lstJoin.Items.Clear();
foreach (var item in result1)
{
string text = "Name: " + item.name + ", Course Id: " + item.courseid + ", Course Name : " + item.coursename;
lstJoin.Items.Add(text);
}
But the "item.coursename" is error, so i can't display it. And then, if I change result1 in foreach with result 2, "item.name" will be error. What should I do so I can display both of them? Thank you.
Why don't you do it in classic way? like SQLiteCommand object with command text:
strCommandText = "SELECT tbl1.*,tbl2.* FROM Table1 tbl1 INNER JOIN Table2 tbl2 ON tbl1.ID = tbl2.ID";
Or is it a specification that you need to use it this way??
Because I had the same issue when I was using the SQLite Helper file.

How to get column names of table at runtime in C#?

Lets say I have a table in SQLServer named MyTable
ID FirstName LastName
1 Harry Dan
2 Maria Vicente
3 Joe Martin
Now if I have to insert any data in table, I will simply fire Insert Query like this
INSERT INTO MyTable (ID, FirstName, LastName) VALUES (4, Smith, Dan);
But what if I don't know the column names beforehand, I only know table name. Then is there a way to get the column name of table at runtime?
You can use sql-
SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('TABLE_NAME')
Or you can query for SELECT TOP 0 * FROM TableName. Then, you can get the columns:
using(var reader = command.ExecuteReader())
{
reader.Read();
var table = reader.GetSchemaTable();
foreach (DataColumn column in table.Columns)
{
Console.WriteLine(column.ColumnName);
}
}
Another option using pure C# / .NET code:
First a helper method, that here returns a simple list of column names. Using a DataTable to hold table schema information, means that other information can also be retreived for each column, fx. if it is an AutoIncreament column etc.
private IEnumerable<string> GetColumnNames(string conStr, string tableName)
{
var result = new List<string>();
using (var sqlCon = new SqlConnection(conStr))
{
sqlCon.Open();
var sqlCmd = sqlCon.CreateCommand();
sqlCmd.CommandText = "select * from " + tableName + " where 1=0"; // No data wanted, only schema
sqlCmd.CommandType = CommandType.Text;
var sqlDR = sqlCmd.ExecuteReader();
var dataTable = sqlDR.GetSchemaTable();
foreach (DataRow row in dataTable.Rows) result.Add(row.Field<string>("ColumnName"));
}
return result;
}
The method can be called as:
var sortedNames = GetColumnNames("Data Source=localhost;Initial Catalog=OF2E;Integrated Security=SSPI", "Articles").OrderBy(x => x);
foreach (var columnName in sortedNames) Console.WriteLine(columnName);
Simply by this Query :
SELECT * FROM sys.columns
WHERE object_id = OBJECT_ID('dbo.[table_name]')
OR This Query :
SELECT COLUMN_NAME
FROM information_schema.columns
WHERE TABLE_NAME = [table_name]
ORDER BY COLUMN_NAME
var ColName = "";
var model = new AttributeMappingSource().GetModel(typeof(DataClassesDataContext));
foreach (var mt in model.GetTables())
{
if (mt.TableName == "dbo.Table_Name")
{
foreach (var dm in mt.RowType.DataMembers)
{
ColName = dm.MappedName + ", ";
Response.Write(ColName);
}
}
}
This question was answered before in various threads
check:
How can I get column names from a table in SQL Server?
How can I get column names from a table in Oracle?
How do I list all the columns in a table?

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