How to alter table from C# code - c#

I want to add one column to an existing table in C#, if it doesn't already exist. I know I have to use an 'alter table' command.
But I am not able to fire that command in my C# code.
How can I do?
I'm using Visual Studio 2010 and Sql Server 2008.

this :
Use [DatabaseName]
Go
if Not exists( Select * from sys.columns As clm
where clm.object_id = OBJECT_ID(N'[TableName]')
And clm.name = N'[ColumnName]'
)
Begin
Alter Table TableName
Add ColumnName DataTypeName
End

Related

Get OUTPUT table from SQL INSERT using .NET

I am attempting to get the OUTPUT table from an INSERT command on a SQL Server database (v14).
DECLARE #i TABLE (TICKET_ID int, CREATED_DATE datetime);
INSERT INTO dbo.TICKET (SITE_ID, TICKET_TITLE, USER_ID)
OUTPUT INSERTED.TICKET_ID, INSERTED.CREATED_DATE INTO #i
VALUES (#s, #t, #q);
SELECT * FROM #i;
I have 3 parameters that are being populated for the site, ticket title and user by #s, #t and #u respectively.
I am calling the command using a SqlClient.SqlDataReader Object with ExecuteReader Function on the 4.5 Framework.
The command successfully inserts the record into the database table, but does not return the table #i with the ticket ID (Auto Increment) and created date (default =GETDATE) which is what I am expected to present to the user once saved to the database.
I have played around with the removing of the #i TABLE in the command, but I get a .NET error:
The target table 'name' of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause
I have found a couple of links that provide some ways to fix these but it did not fix my issue
https://learn.microsoft.com/en-us/previous-versions/dotnet/articles/ms971497(v=msdn.10)?redirectedfrom=MSDN
Cannot use UPDATE with OUTPUT clause when a trigger is on the table
Is there any assistance that can be provided to assist in what I am trying to achieve?
It seems a pain to have to but another option might be just to do this:
INSERT INTO dbo.TICKET (SITE_ID, TICKET_TITLE, USER_ID)
VALUES (#s, #t, #q);
SELECT TICKET_ID, CREATED_DATE
FROM dbo.TICKET
WHERE SITE_ID = #s AND TICKET_TITLE = #t AND USER_ID = #q;
I don't know why you'd need the table. I think you need to just execute this:
INSERT INTO dbo.TICKET (SITE_ID, TICKET_TITLE, USER_ID)
OUTPUT inserted.TICKET_ID, inserted.CREATED_DATE
VALUES (#s, #t, #q);
I can't see any value in the table. When you execute this statement, it'll return results to the client, just like a SELECT statement would.
Hope that helps.

Unable to name table dynamically at creation - c#, sqlite

Using what's available in the System.Data.SQLite namespace and using C# I'm doing database operations. However, there is one problem I can't seem to get figured out.
If I want to create a table which is NAMED DYNAMICALLY AT CREATION, I thought the way to do that would be ...
command.CommandText = #"CREATE TABLE IF NOT EXISTS #tableName( ... )";
and then do this ...
command.Parameters.AddWithValue("#tableName", tableName);
and then do the
command.ExecuteNonQuery();
But what's happening is that I'm getting a new table named "#tableName" instead of whatever the variable tableName is set to.
How can I get this to work correctly?
The way that I approach problems like this is to simplify as much as I can. In this case, simple string substitution should easily resolve your problem without the need to use parameters.
For example:
command.Text = $#"CREATE TABLE IF NOT EXISTS {tableName}( ... )";
or
command.Text = string.Format(#"CREATE TABLE IF NOT EXISTS {0}( ... )", tableName);
Can you create procedure instead of inline query . you can manage easy in stored procedure like this .`CREATE PROCEDURE Dynamic_SP
#Table_Name sysname AS BEGIN
SET NOCOUNT ON;
DECLARE #DynamicSQL nvarchar(4000)
SET #DynamicSQL = N'SELECT * FROM ' + #Table_Name
EXECUTE sp_executesql #DynamicSQL END

How to get custom SQL Server type into Entity Framework generated code

There is a TABLE Type defined in SQL server:
CREATE TYPE RealtySearchResult AS TABLE
(
realtyId int not null,
OwnerId int not null,
...)
And stored procedure:
CREATE PROCEDURE [dbo].[SearchRealty]
(#fulltext nvarchar(200) null,
#skipRows int,
#pageCount int,
....
)
AS
BEGIN
DECLARE #SQL nvarchar(max)
DECLARE #result RealtySearchResult
CREATE TABLE #TEMP
(
realtyId int not null,
OwnerId int not null,
...
)
set #SQL = N'
INSERT INTO #TEMP
SELECT
realty.Id AS realtyId,
realty.OwnerId,
....join with fulltext catalog.... WHERE....#pageCount .....#skipRows'
-- sp_executesql cannot write to local table variable #result,
-- that is why it reads to temp table and then to #result
exec sp_executesql #SQL, N'#skipRows int, #pageCount int', #skipRows, #pageCount
INSERT INTO #result SELECT * FROM #TEMP
SELECT * FROM #result
END
And then in Visual Studio I update the model from database and a new method (wrapper for store procedure SearchRealty) is generated, but it does not contains generated code for returning complex type.
I would expect that EntityFramework should be able to recognize that the store procedure returns defined table type RealtySearchResult and should generate wrapper for it. I am too lazy to write the complex return type by myself in C# again (I just wrote it in SQL). It is really needed?
Can I just generate wrapper for RealtySearchResult type in EntityFramework somehow?
I use Visual Studio 2017 and EntityFramework 6.
It sounds as duplicate as Stored procedure in Entity Framework database first approach but once I click the button Get Column Information I got message "The selected stored procedure or function returns no columns".
Analysis
Based on link Entity Framework not getting column info on a different schema provided by kirsten I realize that EntityFramework execute stored procedure with mode
SET FMTONLY ON
It means it strips all condition and dynamic SQL. This result in empty temporary table and procedure failing during receiving metadata from EntityFramework.
Solution
To help the designer to get metadata without dynamic SQL. Count with that conditions are removed. Following code does a job:
DECLARE #result RealtySearchResult
IF 0=1
BEGIN
SELECT * FROM #result
RETURN
END
During execution of store procedure by EntityFramework (in order to get metadata), condition 0=1 is removed and empty table of Table type is returned which is enough to get metadata. This code is never trigerred in production because of impossible condition.

How to get SCHEMA.TABLES from another database?

I want to get a list of tables exist in another database. for example if i have connected DB1 database and i want to get a list of tables from DB2 then how is it possible?
I know there are some another approaches like connect DB2 and execute insert query to insert schema into #temp table then connect DB1 using USE [DB1] statement and use that #temp table.
But, I don't want to change my sql connection at runtime. Because, there are some dependencies i have created on my sql connection.
UPDATED:
Database can be restored in same server. Now i am using following query to get Table List from the database.
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
version of sql server is 2005.
You need sp_addlinkedserver()
http://msdn.microsoft.com/en-us/library/ms190479.aspx
Example:
exec sp_addlinkedserver #server = 'test'
then
select * from [server].[database].[schema].[table]
Copy Table Schema and Data From One Database to Another Database in SQL Server
Remus Rusanu has already mentioned Here
Try this Query
declare #sql nvarchar(max);
set #sql = N'select cast(''master'' as sysname) as db_name, name collate Latin1_General_CI_AI, object_id, schema_id, cast(1 as int) as database_id from master.sys.tables ';
select #sql = #sql + N' union all select ' + quotename(name,'''')+ ', name collate Latin1_General_CI_AI, object_id, schema_id, ' + cast(database_id as nvarchar(10)) + N' from ' + quotename(name) + N'.sys.tables'
from sys.databases where database_id > 1
and state = 0
and user_access = 0;
exec sp_executesql #sql;
I assume that you've set the database in your connection string.
If the other database is on the same server, you can reference them with a three-part name
select * from otherdb.schema.table
If it's not, you can use a four-part name
select * from otherserver.otherdb.schema.table
But my advice would be to not do that directly but rather create a synonym for each object that you plan to reference externally.
That way you gain some flexibility if you do something like rename the external database.

C# MSSQL alter table then modify values

While the following work fine in SQL Server Management Studio, it just won't work in C#:
DECLARE #PeriodID AS bigint;
SELECT TOP 1 #PeriodID = PeriodID FROM Periods ORDER BY PeriodID DESC;
IF NOT EXISTS(SELECT * FROM information_schema.columns WHERE COLUMN_NAME = N'PeriodID' AND TABLE_NAME = N'MobilePlans')
BEGIN
BEGIN
ALTER TABLE MobilePlans ADD PeriodId bigint NULL
END
BEGIN
UPDATE MobilePlans SET PeriodID = #PeriodID
END
BEGIN
ALTER TABLE MobilePlans ALTER COLUMN PeriodID bigint NOT NULL
END
END
In C#, it keeps telling me Invalid column name 'PeriodID'. and after spending a couple of hours searching, I thought I'd ask here.
While searching, I came across http://bytes.com/topic/c-sharp/answers/258520-problem-sqlcommand-t-sql-transaction, but I couldn't really translate my conditional query to that.
Why can't C# do the same as the Management studio?
Is there another way to do what the query does, that works in C#? I need to perform this on 400 databases, so I'd really like a script to do it for me.
Thanks in advance!
SQL server version is 2008.
Manager version is 2008 (10.0.2531).
.NET framework version is 2.0.
I get "invalid column name 'PeriodID'" running it in Management Studio, if the table doesn't already have the PeriodID column.
Repro:
create table Periods (
PeriodID bigint not null
)
go
insert into Periods(PeriodID) select 1
go
create table MobilePLans (
BLah int not null
)
go
insert into MobilePLans(BLah) select 2
go
DECLARE #PeriodID AS bigint;
SELECT TOP 1 #PeriodID = PeriodID FROM Periods ORDER BY PeriodID DESC;
IF NOT EXISTS(SELECT * FROM information_schema.columns WHERE COLUMN_NAME = N'PeriodID' AND TABLE_NAME = N'MobilePlans')
BEGIN
BEGIN
ALTER TABLE MobilePlans ADD PeriodId bigint NULL
END
BEGIN
UPDATE MobilePlans SET PeriodID = #PeriodID
END
BEGIN
ALTER TABLE MobilePlans ALTER COLUMN PeriodID bigint NOT NULL
END
END
The reason is simple - SQL Server tries to compile each batch completely. If the column already exists, then the UPDATE statement can be compiled. If not, you get the error.
If you put the update inside an Exec:
EXEC('UPDATE MobilePlans SET PeriodID = ' + #PeriodID)
Then it will be compiled at the point that the column does exist.
I guess you have a spelling mistake in your c# code.
The error is saying PeriodeID whereas your column name is PeriodID.
Clarification:
1 - You would like to push this script it against many databases?
2 - Invalid column name 'PeriodeID', I cannot see a column called "PeriodeId", but "PeriodId", is this a typo?
3 - Can you try the same block without main BEGIN/END block?
Is the server collation Case Insensitive ? Because you're adding PeriodId and then updating PeriodID

Categories

Resources