Sending Parameterized DSN into ADO.Net Destination - postgresql

I'm currently using SSIS in Visual Studio 2019 with deployment into a SSISDB Agent on SQL Server 2019. I do not have admin access to the Server.
I am trying to parameterize an ADO.NET Destination that connects to an AWS PostgresQL database. The connection string uses a 32 bit ODBC System based DSN ("DSN=SERVER" minus the quotes is the entirety of the connection string being used, when displayed in the parameter, it is only "SERVER" minus the quotes.)
The error I'm receiving is not a numbered error. It is "The connection string is not valid. It must consist of one or more components of the form X=Y". I know the connection string is working because I can preview the data when in the edit window of the ADO.NET destination and the Parameterized connection string is used, but when I try to run the system, it drops out as soon as the Execute phase starts.
Is there a way to send a parameterized Connection String to an ADO.NET?

Related

How do you specify DB_URI postgres DB connection string to instance running in Google Sql cloud?

Here's my scenario. I have set up an instance of Postgres DB running in the Google SQL cloud. It's up and running and if I whitelist my local IP, I can connect directly with no issue.
I then have deployed a docker container (postGrest) which is a web server that connects to the postgres DB.
When I configured this on Google Cloud Run, it did have a drop-down option where I could specify DB connectivity and it says that, behind the scenes, it configures Cloud SQL Proxy for this connection.
The container allows environment variables to be passed in to specify which server, etc.
One required parameter is the DB_URI to the postgred instance. When running locally, it looks like this:
postgres://authenticator:mysecretpassword#localhost:5432/testdb
When I tried to configure this on the cloud version I tried using the IP 127.0.0.1 (The google cloud SQL proxy documentation says this is how you connect via the proxy). This didn't work.
I then tried using the public-ip assigned to the postgres DB....this didn't work either.
Does anyone know how to specify the correct connection string using this DB_URI format?
I am just going to add this as an answer rather than a comment since it's easier for readability and perhaps helping other users. Please don't feel encouraged to change the accepted answer.
By following the documentation provided by the OP, the final pattern for the URI became:
# Breaking lines for improved readability
POSTGRESS_URI=postgresql:///dbname
?host=/cloudsql/myprojectid:region:myinstanceid
&user=username
&password=password
&sslmode=disable
* dont forget to prefix the unix socket path with /cloudsql/
Any parameters can be used normally as in the example of sslmode.
Also, be aware that two important things are mentioned in the Cloud SQL documentation:
Note: The PostgreSQL standard requires a .s.PGSQL.5432 suffix in the socket path. Some libraries apply this suffix automatically, but others require you to specify the socket path as follows: /cloudsql/INSTANCE_CONNECTION_NAME/.s.PGSQL.5432.
In my case, the program I am using already adds as a suffix .s.PGSQL.5432, so I didn't need to add it to my URI.
Warning: Linux based operating systems have a maximum socket path length of 107 characters. If the total length of the path exceeds this length, you will not be able to connect with a socket from Cloud Run (fully managed).
Cloud Run does not support connecting to Cloud SQL using IP addresses. This means 127.0.0.1 will not work. Cloud Run uses Unix Sockets. You must use a connection string.
The Cloud SQL Proxy connection string looks like this:
myprojectid:region:myinstanceid
You can get the instanceid from the Cloud SQL Instance Details page in the console.
You will also need to add permissions to your Cloud Run service account to access Cloud SQL. You will need at least Cloud SQL Client.
It seems that some postgres client libraries don't support putting user and password parameters in the URL query params. I had problems with pq for Node.js and would get the error "no PostgreSQL user name specified in startup packet".
An alternative way of writing the connection string is as follows:
Breaking lines for readability:
postgres://db_user:db_password#
%2Fcloudsql%2Fproj_name%3Aus-central1%3Asql_instance_name
/db_name&sslmode=disable
It's like a normal TCP connection string, but you put the path to the Unix socket as the host, encoding the / and : characters. If the first character of the hostname is /, then the hostname will be treated as a filesystem path.

Transient problems executing stored procedures on SQL Server 2008 R2

We are having an issue with SQL Server 2008 R2 64 responding to stored procedure call. About every 2 weeks or so, the database stops responding to stored procedures called from an ADO connection/Command set (4.0 framework). We have been working on this for several months now, with little improvement.
System changes:
We upgraded an existing vendor product from SQL Server 2005 to SQL Server 2008 R2 via their upgrade method. The database instance moved from a 32-bit Windows 2003 Server to 64-bit Windows 2008 Server.
The pattern of failure:
The application is run throughout the day, executed by different users via Citrix without issue. Every few weeks, the application stops responding around the same time frame. Once the database stops responding to the hosted instance of the application, any execution of the procedure from the application hangs (installed on CITRIX server, installed on varied physical systems, or debugging in VStudio 2010). After an hour of checking logs, server status, SQL Monitoring tools, tracing the repeated execution attempts, the server decides to respond to the application without intervention.
Strange thing is, when the server is not responding to ADO.Net calls, we execute the stored procedure from SQL Server Management Studio and receive results in 1 to 2 seconds. We are using the same login to access SQL Server Management Studio, and executing the stored procedure with the same parameters.
Looking at the connection string passed to the ADO connection, I don’t see anything unusual:
connectionString="Data Source=myserver\myinstance;Initial Catalog=databaseName;Persist Security Info=True;User ID=xxxxx;Password=yyyyy;Connect Timeout=45"
Tried so far:
Added extra 2gb of RAM to the OS: no change
Added extra tempdb file, expanded size of tempdb log file from 1 to 5gb: reduced the issue from weekly to every 2nd or 3rd week.
Installed SQL Server 2008 R2 SP3: no change.
The black cloud:
To me, the repeating time pattern of failure implies an issue at the database host (server or resource), but the DBAs do not see load or resource issue. If it were purely a host issue, why does it respond to SQL Server Management calls, and not ADO.NET calls?
The last occurrence lasted over two hours, and was resolved after rebooting the database server. Not a great fallback, but desperate times and all…..
Updating the ADO.NET connection to use named pipes has resolved the issue for our application. Prefixing the database name with "np:" has the connection using named pipes.
connectionString="Data Source=np:myserver\myinstance;Initial Catalog=databaseName;Persist Security Info=True;User ID=xxxxx;Password=yyyyy;Connect Timeout=45"
The issue returned on 5/14. This query timeout posting gave us hints how to force SQL Management Studio to behave like the ADO.NET connection and allowed us to recognize this is a "parameter sniffing" issue. We have applied changes to disable the parameter sniffing within the stored procedure.

Creating a linked server from SQL Server 2008r2 to Access 2003

I've written a web app in ASP.NET that stores all of it's data in SQL Server 2008r2 and runs everything via stored procedures. The app is collecting data for a department who wants 2-3 pieces of that data pushed to an old app they use which has a Microsoft Access 2003 backend (.MDB file). My thought was to create a linked server to Access so my app can push everything to SQL server and it can handle it from there (seemed simple enough). Based on info from MSDN (here and here), I was using the following SQL command to create the linked server:
EXEC sys.sp_addlinkedserver #server = N'CMPtesting' ,
#datasrc = N'\\srv.local\SHAREDOCS\MPS\CMPdata.mdb' ,
#srvproduct = N'Access' ,
#provider = N'Microsoft.Jet.OLEDB.4.0'
This completes successfully, and I can see my CMPtesting server listed under Server Objects -> Linked Servers. However, if I try to verify the server using this:
SELECT name FROM [CMPtesting].master.sys.databases
or even just view the tables, I get an error:
OLE DB provider 'Microsoft.Jet.OLEDB.4.0' cannot be used for distributed queries because the provider is configured to run in
single-threaded apartment mode. (Microsoft SQL Server, Error: 7308)
Researching that error led me to "SQL to Access linked server" which suggested installing some different Access drivers and then using #provider = N'Microsoft.ACE.OLEDB.12.0' instead of the Jet driver. Again, this completes successfully, but attempting to view the tables produces a different error:
Cannot create an instance of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "CMPtesting". (Microsoft
SQL Server, Error: 7302)
I know this is not simply an invalid driver error, because if I just make up a provider name I get this instead:
The OLE DB provider "foobar" has not been registered. (Microsoft SQL Server, Error: 7403)
I'm not sure what else to try because all my searches just turn up more rehashing of how to run sp_addlinkedserver without any additional details or help with these errors.

Error code 40 when running SSRS reports from Internet Explorer (run as administrator)

We deployed a VB.Net application on a customer's computer that contains SSRS reports.
The application connects to the SQL Server database in the app without any problems. We installed SQL Server Data Tools so we could deploy the reports (rdl) and data source (rdl) files up to the report server. These deploy without any problems.
In SQL Server Data Tools we can "Preview" the reports without any problems as well.
We do run into a problem when attempting to view the report from Internet Explorer (run as an administrator).
We get the following error:
Cannot create a connection to data source 'DataSourceReports'
(this is the name we used for the TargetDataSourceFolder)
error:40 - Could not open a connection to SQL Server
We also get the same error when the app we deployed runs the reports.
Please let us know what is not set up correctly on the SQL Server side.
A likely possibility is that you are experiencing a double hop authentication problem. It's not clear from your explanation, but is the SQL Server database on a separate server from the report server? If so, then your credentials allow you to connect to the report server but Windows integrated security does not pass those credentials on to the SQL Server database if you are using NTLM on the report server. The report server tries to use Kerberos on your network to authenticate by way of ticketing to the SQL Server database, but you must have this configured correctly on your network. See this article if you want to use Kerberos: http://technet.microsoft.com/en-us/library/ff679930(v=sql.100).aspx.
Another (easier) solution is to open the data source on the report server and change the authentication to use stored credentials. Make sure the credentials you use have read permission on the SQL Server database. The downside of this approach is that you cannot use row-level security in your report by user unless you design your report to capture user information and set up the query or a filter on the dataset to restrict data by user. If that's not a concern, the stored credentials are easy to set up and maintain - and you're going to have to do this anyway if you want to use caching, snapshots, or subscriptions. For more information on stored credentials, see http://msdn.microsoft.com/en-us/library/ms159736.aspx.

How to set connection string for all developers?

We are working with the Entity Framework, and most of the developers have named instances of SQL Server 2008 R2.
The connection strings that EF uses look like:
<add name="MyConnectionString"
connectionString="Data Source=MyInstance\MySource;
Initial Catalog=MyDatabase;
Integrated Security=True"
providerName="System.Data.SqlClient" />
So the problem, for multiple developers, is that the data source is different for everyone.
Previously, I'd use an ODBC DSN to get around this problem, but according to this post that's not directly available.
Is there a way to set up the connection string so that everyone's different data source can be accessed?
We use aliases for that in our project. Every developer should create an alias with the same name (e.g. Entitydatabase) that points to his/her named instance, so the connection string can be the same.
You can create an alias in Sql Server Configuration Manager, inside the SQL native client configuration node. The best is to set it for both 32 and 64 bits (if you have a 64 bit server installed). Also make sure to enable the client protocols you want to use (e.g. TCP or named pipes) to get it work.
Finally, in the connection string simply use the alias name as datasource.