Get Database's Tables - c#

I want to write a query to get the names of tables of a specific database, but I don't know how can write it.
I want to execute this query for MS Access 2007 and Oracle 11g.
Thanks

If you want raw, direct queries:
For Oracle:
SELECT * FROM user_tables
For MS Access:
SELECT * FROM MSysObjects WHERE [Type] In (1, 4, 6)
(sorting and advanced filtering omitted for brevity.)

Related

SQL Server table to table bulk insert using C#

I need to insert around 5 million rows of data from one table to another using C#. Please recommend a good way to do this. Thanks.
write a Stored Procedure or query and then run it from C# code.
the query will look like this -
INSERT INTO table2
SELECT * FROM table1;

What is the best way to fetch records batch-wise from SQL Server

Scenario: we are fetching rows from SQL Server to C#.Net console application and doing action on the retrieved data from SQL Server through stored procedure; after the action is performed the new data is stored into the MongoDB using C#-MongoDB-Driver.
Issue: There are billions of rows. My stored procedure contains query as follows:
select * from table_name
To work out some batch-wise logic there is no identity column nor any date columns or such.
Information: As of now the application is fetching the records upto 3500 - 5000 records and storing into MongoDB and then it throws an error which is as follows:
System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
Question: Can anyone suggest me some logic to work out for batch-wise read/fetch from SQL Server?
If you can't use OFFSET-FETCH in SQL Server 2012 and assuming the table has a primary key or column(s) that allow you to uniquely identify a row, lets call it UniqueKey, then in 2005 upwards you could use ROW_NUMBER like this...
SELECT UniqueKey, col2, col3
FROM
(
SELECT UniqueKey, col2, col3, ROW_NUMBER() OVER (ORDER BY UniqueKey) AS RowNum
FROM YourTable
) sub
WHERE sub.RowNum BETWEEN #startRow AND #endRow
If you use MSSQL 2012 try OFFSET-FETCH clause. It is the best solution!
Example: SELECT … ORDER BY orderid OFFSET 25 ROWS fetches only the next 25 rows.
It means this query will return from 25 to 50 records. The ORDER BY clause is mandatory, so if you don't want to use order, use ORDER BY (SELECT NULL)

Why linq fail to get temp table values

work on C# vs2008. I have a stored procedure ,This procedure holds temp table ,i need to get the temp table values.My sql query is bellow:
create procedure [dbo].[TestProcedure]
as
SELECT * INTO #temp1 from(select * from DischargePort) as b
select * from #temp1
drop table #temp1
My above query has a temp table named #temp1.After run this query in sql-server-management i get result ,but when i try to execute this procedure in linq ,I get no result.My linq syntax is bellow:
var r = ProviderName.TestProcedure();
Can anybody tell me why this problem arise,How to overcome this problem.Hope any body not say that linq can not handled the temp table or this kind of word.if have any query plz ask .Thanks in advance.
I don't think this is anything to do with the temporary table, but rather that Linq does not know what output is to expected.
With Dotnet Framework 4, this is easy, as you can do something like
(from r in ProviderName.TestProcedure().AsDynamic()
select new { r.Id, r.Description}).ToList()
(assumes Id and description are fields in DischargePort)
Otherwise, you need to do something in your designer to tell Linq what your procedure outputs. I have never had to do this, but perhaps this article will help.
When I think about it, in this particular case, you should be able to do something like
var results = (from r in ExecuteQuery<DischargePort>("exec TestProcedure")
select r ).ToList();
i would start by downloading linqpad to see the sql that linq is emitting, this may provide some clues. you could also use the sql profiler tool to see what query is being run.

how can i check whether a table exists in the database (ACCESS or SQL) in C#

I found a lot of questions regarding with this question.
But is there any simple statements to accomplish this task?
for both SQL and ACCESS
IF (EXISTS (SELECT 1 FROM sys.tables WHERE name = 'table_name'))
BEGIN
-- do stuff
END
sys.tables can also give you some information about the table object, e.g. the is_replicated column tells you if the table was created by replication or the has_replication_filter column tells you if the table has a replication filter set up
NB: this is for SQL Server
Edit:
For Access:
SELECT COUNT(*) as Exists from MsysObjects
WHERE type = 1
AND name = 'MY_TABLE_NAME'
Note that there is no standardized way to do this in SQL, you will have to write plattform-specific code.
To my knowledge, all DBMS have this functionality in one way or another, but it differs greatly, eg in Oracle you can query the sys.all_tables view.
You can also do using OBJECT_ID.
IF OBJECT_ID('table1') IS NOT NULL
print 'Exists'
else
print 'Not Exists'

How do I determine if I have execute permissions on a DB programatically?

I have a Windows Service that requires execute permissions on a SQL Server 2005 DB. On start up I check to see if I can connect to the DB and stop the service if I can't. I also want to do a check to see if I can execute a stored procedure using that connection. Is there a way to do that without actually attempting to execute a sproc and looking at the exception if one occurs?
SQL 2005 and on you can check any permission with HAS_PERM_BY_NAME:
SELECT HAS_PERMS_BY_NAME('sp_foo', 'OBJECT', 'EXECUTE');
you could run a query like this:
SELECT
o.NAME,COALESCE(p.state_desc,'?permission_command?')+' '+COALESCE(p.permission_name,'?permission_name?')+' ON ['+SCHEMA_NAME(o.schema_id)+'].['+COALESCE(o.Name,'?object_name?')+'] TO ['+COALESCE(dp.Name,'?principal_name?')+']' COLLATE SQL_Latin1_General_CP1_CI_AS AS GrantCommand
FROM sys.all_objects o
INNER JOIN sys.database_permissions p ON o.OBJECT_ID=p.major_id
LEFT OUTER JOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id
where p.state_desc='GRANT' AND p.permission_name='EXECUTE'
AND o.NAME='YourProcedureName'
AND dp.Name='YourSecurityName'
...and remove the fancy formatting of the grant command, it is there only for reference
these are nice too...
SELECT * FROM fn_my_permissions('YourTable', 'OBJECT')
SELECT * FROM fn_my_permissions('YourProcedure', 'OBJECT')
SELECT * FROM fn_my_permissions (NULL, 'DATABASE')
SELECT * FROM fn_my_permissions(NULL, 'SERVER')
To see what permissions someone else has you can do this:
EXECUTE AS user = 'loginToTest'
GO
PRINT 'SELECT permissions on tables:'
SELECT
HAS_PERMS_BY_NAME( QUOTENAME(SCHEMA_NAME(schema_id))+'.' + QUOTENAME(name)
,'OBJECT','SELECT'
) AS have_select
, *
FROM sys.tables;
PRINT 'EXECUTE permissions on stored procedures:'
SELECT
HAS_PERMS_BY_NAME( QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name)
,'OBJECT', 'EXECUTE') AS have_execute
, *
FROM sys.procedures;
GO
REVERT;
GO
The first part of this answer shows how you can check rights in T-SQL, the second part gives an example how to use this in the Entity Framework (note that there are differences between the EF versions - the example given is EF 4, but can be changed easily to a newer version):
First part (SQL):
I am using the following T-SQL script to check permissions. It first checks if you have any rights, then it checks execute permissions for the SPs, finally select permissions for the tables. See this link to get more information.
-- 1. Do I have any permissions?
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;
-- 2. create list of schemas
declare #SchemaList table (schema_id int, name nvarchar(max));
PRINT 'Schemas regarded:'
insert into #SchemaList
select distinct schema_id, name FROM sys.schemas
where name in ('dbo') -- enter the schemas you like to check comma-separated
SELECT s.name, s.schema_id FROM sys.schemas s
join #SchemaList sl on s.schema_id=sl.schema_id
-- 3. check execute permissions
PRINT 'EXECUTE permissions on stored procedures:'
SELECT
HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)
,'OBJECT', 'EXECUTE') AS [have execute]
,'['+s.name +'].['+ t.name+']' as [object]
--, *
FROM sys.procedures t
join #SchemaList s on t.schema_id=s.schema_id
order by s.name, t.name;
-- 4. check select permissions
PRINT 'SELECT permissions on tables:'
SELECT
HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id))+'.' + QUOTENAME(t.name)
,'OBJECT','SELECT') AS [have select]
,'['+s.name +'].['+ t.name+']' as [object]
--, *
FROM sys.tables t
join #SchemaList s on t.schema_id=s.schema_id
order by s.name, t.name;
With the Northwind database for example, this gives you the following result:
Note that you can configure the schemas regarded in step 2. If you don't need a limited set of schemas checked, you can just comment out the where clause in the insert into #SchemaList statement to get all schemas.
Second part (Entity Framework):
In this section, I'd like to show you, how you can get the results into Entity Framework.
Let's suppose you want to check if you have any rights before using any of the tables in your LINQ queries. Take a look at this example (for simplicity, I've done it in LinqPad, please add System.Data.Entity.dll and its namespaces via F4 before you run it):
void Main()
{
var dc=this;
var sql="SELECT TOP 1 "
+ "HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;";
var result=dc.ExecuteStoreQuery<Rights>(sql);
if (result1.DoIHaveAnyRights==1)
{
Console.WriteLine("OK"); // ok
}
else
{
// no rights: Show error etc.
Console.WriteLine("No rights"); // ok
}
}
public class Rights
{
public Int32 DoIHaveAnyRights { get; set; }
}
Likewise you can use the query from the first part of my answer, e.g.:
var sql="select top 1 case when cnt.NoRightsCount=0 then 1 else 0 end "
+"as DoIHaveAnyRights "
+"from (SELECT count(1) NoRightsCount FROM sys.procedures t "
+"where HAS_PERMS_BY_NAME("
+"QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)"
+",'OBJECT', 'EXECUTE')<>1) cnt";
This query will check if there are any stored procedures in your database for which you have no rights to execute - in this case the return value would be result1.DoIHaveAnyRights!=1.
I think you get the idea, play around with the possibilities: Keep in mind that EF requires access to all the database tables, stored procedures etc. you're mapping to - you could use the code above to check before you access them. Unfortunately, there is currently no easier way to do this.
You would have to have rights to access the DataDictionary for your database and run a query against it to determine which permissions the account you log in with has. This would vary from database to database.

Categories

Resources