Bug with multiple TADOConnections - sql-server

I already figured out a display table bug using ADO and SQL Server and different connections to one database. ( see details at BUG #1 )
Another issues come while trying to delete records
The code goes like this
function resettable (tablename, databasename, servername) : Boolean;
var
aADOQuery : TADOQuery;
aADOConnection : TAdoConnection,
begin
/// Create ADO stuff
aADOQuery := TADOQuery.Create;
aADOConnection := TAdoConnection.Create;
/// connect to DB & Table
....
///
aADOQuery.sql.add('delete * from ' + Tablename;
aADOQuery.execsql;
/// free objects after use
....
end;
This code works fine when the ADOConnection is alone on the database. If there has been some activity by any other ADO connection and some modification done, the code fails while the "database is not updated error message"
How to create a solution which will do an update prior to the delete record statement ???

Related

How to execute stored procedure on ODBC Snowflake Destinastion?

I'am building new package for move data from aws sql server instance to snowflake odbc destination. If i found rows which was updated i must change them on snowflake as well. In common's i found only 'OLE DB Command' for execute procedure for update diffrent rows.
The problem is i need something like "ODBC Command" for execute procedure to update diffrent rows between SQL Server&Snowflake.
OK, I do it.
So if u need UPDATE rows on ODBC destination in SSIS u have only one way to do that u need to use Script Component. Before I thought it will be something like ODBC Command and we will need to write stored procedure to change rows in the destination. I link that for ppl who care in the future.
The OLE DB Command transformation runs an SQL statement for each row in a data flow. For example, you can run an SQL statement that inserts, updates, or deletes rows in a database table.
Microsoft OLE DB Command description
I wrote a simple code in c# to Update Rows and it works perfectly. U can simple rebuild it for execute procedure or do whatever u need.
public class ScriptMain : UserComponent
{
OdbcConnection odbcConn;
OdbcCommand odbcCmd;
OdbcParameter odbcParam;
public override void AcquireConnections(object Transaction)
{
/// Create a String base on that which u define on package for connection and
adding a password
string connectionString;
connectionString = this.Connections.SFConnection.ConnectionString;
odbcConn = new OdbcConnection(connectionString + "PWD=YOURPASSWORD");
odbcConn.Open();
}
public override void PreExecute()
{
///Create command which we wanna execute
base.PreExecute();
odbcCmd = new OdbcCommand("UPDATE klienci SET IMIE= ?,NAZWISKO= ? ,NUMER_TELEFONU= ? ,EMAIL= ? ,ULICA= ? ,MIASTO= ? ,STATE= ? ,ZIP_CODE = ? WHERE CUSTOMER_ID= ?", odbcConn);
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
///Adding parameters and connecting them with our input column from package
odbcCmd.Parameters.AddWithValue("#IMIE", Row.Sourcefirstname);
odbcCmd.Parameters.AddWithValue("#NAZWISKO", Row.Sourcelastname);
odbcCmd.Parameters.AddWithValue("#NUMER_TELEFONU", Row.Sourcephone);
odbcCmd.Parameters.AddWithValue("#EMAIL", Row.Sourceemail);
odbcCmd.Parameters.AddWithValue("#ULICA", Row.Sourcestreet);
odbcCmd.Parameters.AddWithValue("#MIASTO", Row.Sourcecity);
odbcCmd.Parameters.AddWithValue("#STATE", Row.Sourcestate);
odbcCmd.Parameters.AddWithValue("#ZIP_CODE", Row.Sourcezipcode);
odbcCmd.Parameters.AddWithValue("#CUSTOMER_ID", Row.Sourcecustomerid);
odbcCmd.ExecuteNonQuery();
}
}

SQL Server : get messages from referenced entities procedure in code

I'm running big dependency scan on legacy db and see that some objects have obsolete ref links, if you run this code in SSMS for View that points to not existing table like in my case, you will get your output on Results tab AND error info in Messages . Like in my case below.
I tried to check all env things I know and output of this stored procedure, but didn't see any indication.
How I can capture this event as I'm running this in looped dynamic SQL script and capture output in my table for further processing?
Updated:
it just text in Message box ,on error, you still have output on
Results tab
this is sp, it loop thru object list I took from sys.object and run this string as my sample to get all dependencies, load all into table. This call to
sql_reference_entities is the only way to get inter database
dependency on column level. So I need stick to this 100$>
--
Select *
From sys.dm_sql_referenced_entities('dbo.v_View_Obs_Table','Object')
--
----update------
This behavior was fixed in SQL Server 2014 SP3 and SQL Server 2016 SP2:
Starting from Microsoft SQL Server 2012, errors raised by
sys.dm_sql_referenced_entities (such as when an object has undergone a
schema change) cannot be caught in a TRY...CATCH Transact-SQL block.
While this behavior is expected in SQL Server 2012 and above, this
improvement introduces a new column that's called is_incomplete to the
Dynamic Management View (DMV).
KB4038418 - Update adds a new column to DMV sys.dm_sql_referenced_entities in SQL Server 2014 and 2016
----update-------
The tldr is that you can't capture these on the server side, and must use a client program in C#, PowerShell or some other client that can process info messages.
That DMV is doing something strange that I don't fully understand. It's generating errors (which a normal UDF is not allowed to do), and those errors do not trigger a TRY/CATCH block or set ##error. EG
create table tempdb.dbo.foo(id int)
go
create view dbo.v_View_Obs_Table
as
select * from tempdb.dbo.foo
go
drop table tempdb.dbo.foo
go
begin try
Select * From sys.dm_sql_referenced_entities('dbo.v_View_Obs_Table','Object')
end try
begin catch
select ERROR_MESSAGE(); --<-- not hit
end catch
However these are real errors, as you can see running this from client code:
using System;
using System.Data.SqlClient;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
using (var con = new SqlConnection("Server=.;database=AdventureWorks;integrated security=true"))
{
con.Open();
con.FireInfoMessageEventOnUserErrors = true;
con.InfoMessage += (s, a) =>
{
Console.WriteLine($"{a.Message}");
foreach (SqlError e in a.Errors)
{
Console.WriteLine($"{e.Message} Number:{e.Number} Class:{e.Class} State:{e.State} at {e.Procedure}:{e.LineNumber}");
}
};
var cmd = con.CreateCommand();
cmd.CommandText = "Select * From sys.dm_sql_referenced_entities('dbo.v_View_Obs_Table','Object')";
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read() || (rdr.NextResult() && rdr.Read()))
{
Console.WriteLine(rdr[0]);
}
}
Console.ReadKey();
}
}
}
}
outputs
Invalid object name 'tempdb.dbo.foo'.
Invalid object name 'tempdb.dbo.foo'. Number:208 Class:16 State:3 at v_View_Obs_Table:4
0
The dependencies reported for entity "dbo.v_View_Obs_Table" might not include references to all columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity. Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist.
The dependencies reported for entity "dbo.v_View_Obs_Table" might not include references to all columns. This is either because the entity references an object that does not exist or because of an error in one or more statements in the entity. Before rerunning the query, ensure that there are no errors in the entity and that all objects referenced by the entity exist. Number:2020 Class:16 State:1 at :1

Refcursor in stored procedure with postgres

I am a rookie/newbie in the postgres data access api. I have worked a bit on oracle, sql server and trying to do what i have done with those dbms
The use is very simple
1) a stored procedure aka function with input params
2) Returning or more ref cursors
3) Using an ent lib wrapper to use the npgsql provider/database with it
4) Doing a data adapter fill and running into the issue with some cursor de-referencing.. it appears though i am inside a tran..
5) I just want to get some simple working sample with the latest npgsql provider..
Here is my function
CREATE OR REPLACE FUNCTION public.geterrorcategories(
v_organizationid integer)
RETURNS refcursor
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE cv_1 refcursor;
BEGIN
open cv_1 for
SELECT errorCategoryId, name, bitFlag
FROM ErrorCategories
ORDER BY name;
RETURN cv_1;
END;
$BODY$;
The code using the enterprise lib api/wrapper is as follows.
/// <summary>
/// Executes GetErrorCategories in case of SQL Server or GetErrorCategories for Oracle
/// </summary>
public static DataTable GetErrorCategoriesAsDataTable(string dbKey ,int? ORGANIZATIONID)
{
DataTable tbl = new DataTable();
Database db = Helper.GetDatabase(dbKey);
using (DbConnection con = db.CreateConnection()){
con.Open();
var tran = con.BeginTransaction();
using (DbCommand cmd = con.CreateCommand()){
cmd.Transaction = tran;
BuildGetErrorCategoriesCommand(db, cmd ,ORGANIZATIONID);
cmd.CommandText = "GetErrorCategories";
try {
Helper.FillDataTable(tbl, db, cmd);
con.Close();
} catch (DALException ) {
throw;
}
}
}
return tbl;
}
The command is built as follows.
private static void BuildGetErrorCategoriesCommand(Database db, DbCommand cmd ,int? ORGANIZATIONID){
Helper.InitializeCommand(cmd, 300, "GetErrorCategories");
db.AddReturnValueParameter(cmd);
db.AddInParameter(cmd, "organizationId", DbType.Int32, ORGANIZATIONID);
db.AddCursorOutParameter(cmd, "CV_1");
}
I am not getting any error. I get only 1 row back which i think is this un_named_portal_1 or something but not the results from my table which my query returns
It is frustrating as i would like to keep my application code the same as much as possible but would like to switch providers at run time. I am using a tweaked 'ent lib' contribution database that was created for npgsql.
Hope this helps to point me to the right areas to look for..
There is absolutely no reason above to declare your PostgreSQL function to return a cursor - you can simply return a table, see the PostgreSQL docs for more info.
Npgsql originally had a feature where it automatically "dereferenced" cursors returned from functions, but this has been removed. For more information about this see this issue (warning, it's long...). Some people are requesting that the feature be returned.

Merge aspnetdb.mdf with my own database (automatically generated)

I've searched the internet thoroughly but couldn't find a clear answer to the problem. I have got the aspnet.db database. But i want to add my own tables and data to this database. If i try to connect to it with the connection string:
<add name ="ToernooiCompanionDBContext" connectionString ="Data Source= .\SQLEXPRESS; Integrated Security = SSPI; Trusted_Connection=True; Initial Catalog= aspnetdb" providerName ="System.Data.SqlClient"/>
A new database will be created (aspnetdb.mdf) in C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA.
I want the database (which is automatically generated by codefirst) to merge with the existing one in my APP_DATA folder. What am I doing wrong?
I've tried adding AttachDbFilename=|DataDirectory|aspnetdb.mdf and User Instance=true to my connection string, or using the LocalSqlServer connection string which is defined in machine.config, but in all cases this overwrites the existing database. If I remove Initial Catalog=aspnetdb then I get an error that the initial catalog is needed.
I had the same problem but this link got me on the track to something that worked at least for me. I hope this helps someone at least! :)
Create a database
Add the aspnet tables to the new database
Fix the database connections in web.config so they point to the same database
Write some sql that removes all tables except the ones that start with "aspnet_"
Add the sql to the database initializer you write by your self
Add a call to the database initializer in Global.asax.cs
1. Create a database
I usually do this with SQL Server Management Studio. The database I used for this example code is SQL Server 2008R2 but I have done the same with SQL Server Express that you use.
2. Add the aspnet tables to the new database
I use the following tool which if you use it without any command line arguments works like a wizard.
%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe
3. Fix the database connections so they point to the same database
The following two lines are from the test application I made. Notice that the name of the second connectionstring (MyHealthContext) is identical to the name of the DbContext I am using for my code first classes.
DbContext:
public class MyHealthContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<PersonAttribute> PeopleAttributes { get; set; }
}
Web.config
<add name="ApplicationServices" connectionString="Server=localhost\mssql2008r2;Database=MyHealth;Integrated Security=True;" providerName="System.Data.SqlClient"/>
<add name="MyHealthContext" connectionString="Server=localhost\mssql2008r2;Database=MyHealth;Integrated Security=True;" providerName="System.Data.SqlClient"/>
4. SQL that removes all but the aspnetdb-tables
DECLARE #cmdDropConstraints VARCHAR(4000)
DECLARE #cmdDropTables VARCHAR(4000)
-- ======================================================================
-- DROP ALL THE FOREIGN KEY CONSTRAINTS FROM THE TABLES WE WANT TO DROP
-- ======================================================================
DECLARE cursorDropConstraints CURSOR FOR
SELECT
'ALTER TABLE ['+ s.name + '].[' + t.name + '] DROP CONSTRAINT [' + f.name +']'
FROM
sys.foreign_keys f
INNER JOIN sys.tables t ON f.parent_object_id=t.object_id
INNER JOIN sys.schemas s ON t.schema_id=s.schema_id
WHERE
t.is_ms_shipped=0
AND t.name NOT LIKE 'aspnet_%'
AND t.name <> 'sysdiagrams'
OPEN cursorDropConstraints
WHILE 1=1
BEGIN
FETCH cursorDropConstraints INTO #cmdDropConstraints
IF ##fetch_status != 0 BREAK
EXEC(#cmdDropConstraints)
END
CLOSE cursorDropConstraints
DEALLOCATE cursorDropConstraints;
-- ======================================================================
-- DROP ALL THE RELEVANT TABLES SO THAT THEY CAN BE RECREATED
-- ======================================================================
DECLARE cursorDropTables CURSOR FOR
SELECT
'DROP TABLE [' + Table_Name + ']'
FROM
INFORMATION_SCHEMA.TABLES
WHERE
Table_Name NOT LIKE 'aspnet_%'
AND TABLE_TYPE <> 'VIEW'
AND TABLE_NAME <> 'sysdiagrams'
OPEN cursorDropTables
WHILE 1=1
BEGIN
FETCH cursorDropTables INTO #cmdDropTables
IF ##fetch_status != 0 BREAK
EXEC(#cmdDropTables)
END
CLOSE cursorDropTables
DEALLOCATE cursorDropTables;
5. Code for the database initializer:
Replace the "SQL CODE GOES HERE" below with the sql from step 4
public class MyHealthInitializerDropCreateTables : IDatabaseInitializer<MyHealthContext>
{
public void InitializeDatabase(MyHealthContext context)
{
bool dbExists;
using (new TransactionScope(TransactionScopeOption.Suppress))
{
dbExists = context.Database.Exists();
}
if (dbExists)
{
// Remove all tables which are specific to the MyHealthContext (not the aspnetdb tables)
context.Database.ExecuteSqlCommand(#"SQL CODE GOES HERE");
// Create all tables which are specific to the MyHealthContext (not the aspnetdb tables)
var dbCreationScript = ((IObjectContextAdapter)context).ObjectContext.CreateDatabaseScript();
context.Database.ExecuteSqlCommand(dbCreationScript);
Seed(context);
context.SaveChanges();
}
else
{
throw new ApplicationException("No database instance");
}
}
protected virtual void Seed(MyHealthContext context)
{
//TODO: Add code for seeding your database with some initial data...
}
}
6. Code that hooks in your new database initializer
To make sure that the custom database initializer isn't accidentily run in the production environment i added a #if DEBUG statement since I always compile my code in release mode before publishing.
protected void Application_Start()
{
//TODO: Comment out this database initializer(s) before going into production
#if DEBUG
Database.SetInitializer<MyHealthContext>(new MyHealthInitializerDropCreateTables()); // Create new tables in an existing database
#endif
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
Open ASPNetDB db in sql server by attaching as new database
Make Creation scripts of tables / Stored proce3dures from ASPNetDB and run in your own database to create tables in your database
Open web.config of your application and attach application to your own database. Copy the name of connection string
Go to membership area and replace connectionstring name with copied one
Do above step with area as well

Delphi 5.0 Open Interbase/FireBird connection via code

This is old stuff! Is related to delphi 5.0 and interbase 1.6.
I'm trying to open a DB connection via code. But this code is related to enabling the connection, all the components were added using delphi drag-drop User Interface: DataSource1, TForm1, DBGrid, DBNavigator etc..
procedure TDataModule2.DataModuleCreate(Sender: TObject);
begin
database.DatabaseName:='C:\MyDatabase.GDB';
database.Connected := true;
database.Open;
IBTransaction.Active := true;
myTable.Open;
end;
I have a TForm with DBGrid and DBNavigator component. I also have a TIBQuery (that DataSource1 is associated to) with this code on the SQLStrings:
SELECT * FROM NEW_TABLE
On the Form I have this code to enable DBNavigator and DBGrid to show the DB Values. The DB is very simple is just a table: NEW_TABLE with a NEW_VALUE of VARCHAR type
procedure TForm1.FormCreate(Sender: TObject);
begin
DataSource1.DataSet.Open;
// This will call the query associated to this DataSource1 the tibQuery1 to call
// SELECT * FROM NEW_TABLE, but the message below appears: IBClientError...
end;
The message appears:
IBClientError with message 'Database not assigned'
OBS1: If I connect the components by hand on delphi user interface, the connection with the DB is established.
You have to assign the Database property of your query, something like:
IBQuery1.Database := MyDatabase;

Resources