ADODB Command Parameters Refresh doesn't retrieve parameters - sql-server

I have an old web application, built with VBScript on an IIS6 Server with a SQL Server 2008 database. It is in the processed of being moved to a new server, on IIS8.
Every queries in the app work with stored procedures, with which we never had a problem. But on the new server, it doesn't seem to work. I found it it's because the Command.Parameters.Refresh doesn't return the parameters properly.
Consider this code:
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandType = 4
cmd.CommandText = v_strSpName
cmd.CommandTimeout = 0
cmd.Parameters.Refresh
For i = LBound(v_arrParameters) To UBound(v_arrParameters)
If m_bReplaceEmptyToNull Then
v_arrParameters(i)(1) = ReplaceEmpty(v_arrParameters(i)(1))
End If
cmd.Parameters(v_arrParameters(i)(0)).value = v_arrParameters(i)(1)
Next
Everything in v_arrParameters exists, but I tried iterating in Parameters.name after the refresh, the parameters are not returned (but they are on the production server).
Also worth noting, the SQL Profiler does receive the query and return the parameters:
exec [Database]..sp_procedure_params_rowset N'get_company',1,N'dbo',NULL
According to this page, it is a known issue, I just want to make sure it doesn't come from this problem, and find a solution or an alternative that doesn't imply a full rewriting of the application.
Also, no I can not update the SQL Server version, switch to VB.NET, there is always the issue that there is a client that won't pay for this problem.

So we managed to make it work this way:
Opening the Applications Pools section in IIS Manager.
Going in the Advanced Settings of the Default App Pool (its name here, maybe not for everyone, I don't know)
Setting Enable 32-bits apps to True
This is on a 64-bit Windows Server 2012 R2, with Microsoft SQL Server 2008 (SP4) - 10.0.6241.0 (X64) .

Related

Connecting to SQL Server in a remote server from Access

We have a Server A and a Server B.
In Server A we have our ERPs made in Access and VBA.
In Server B we have an instance of SQL Server that needs to stay in that server.
Some Access databases need to link to some tables from that SQL Server instance and I don't want the password to be stored in the MSysObjects table, so I cannot manually link the tables checking the save the connection option.
I saved the connection string in a table with password obfuscation. With that connection string I re-link the tables on startup.
The instance is accessed through it's IP, not the name of the instance. If I use the name of the instance it doesn't work.
It works for me but not for other users except one.
The SQL Server instance has been properly configured to allow remote connections, the ports have been opened and rules added to firewall. If it wasn't properly configured it wouldn't work for me and the other user, so I'm pretty confident in that. The same with the connection string and the methods to stablish the connection in Access.
What I've tried:
Installing the SQL Native Client 11.0.
Installing a full SQL Server Express.
Configured the SQL Browser service to star automatically instead of being disabled.
Step 1 did not work for any user. Step 2 did work for one user but not for the rest. Step 3 did not had any effect. For me I had it installed in my machine since forever, so it doesn't apply.
If I try to do the same with a SQL Server instance in our LAN it works for every user, but not when the instance is in a remote server.
Note I have limited knowledge. Maybe I say something that does not make sense.
Ok, a few things:
Installing the SQL Native Client 11.0.
Ok, then you have to re-link the tables - choose the new driver. A refresh of the linked tables is NOT sufficent. And this ALSO means that each work station ALSO now must have native 11 instlled. And if you say decide to link using native 17 (a much newer odbc driver), then AGAIN YOU must install this native driver on each work station. While you can install multiple sql drivers on each workstation, the driver you used to link the tables MUST ALSO be installed and exist on each work station.
Installing a full SQL Server Express.
Why? What would installing a copy of sql server have to do with OTHER sql servers on other machines that you are attempting to connect to? You think installing sql server on a machine effects the sql server running say on amazon.com? So, this move makes no sense at all.
You are attempting to connect to some instance of sql server running on some other computer. Makes no sense nor will it help to install some copy of sql server that you not using, not connecting to, and that has zero to do with this issue.
Configured the SQL Browser service to star automatically instead of being disabled.
Where? The browser service is set to run and startup on the server and SAME machine where sql server is installed and running. So, yes, without question, those two sql servers A, and B most certainly MUST have the sql browser service running. That service is what allows the client computers to connect to that running instance of sql server. In the past, older (previous) versions of sql server would allow a default connection, but now in near all cases, you MUST ensure that the sql browser service is running on that computer that also has the database you are attempting to connect to.
it's worth to note that the instance is accessed through it's IP, not the name of the instance.
No, you likly have this incorrect. There are two part.
The server name - and then the "instance" of sql server running.
While you can swap out (not use) the server name, you STILL WILL NEED to specify the sql server instance.
So, you can use this format:
myservername\SQLEXPRESS
Or, you can replace the server with a IP address, but you STILL NEED the sql server instance. (by default, it is SQLEXPRESS - but you have to check what the instance of sql server database is).
192.168.1.30\SQLEXPRESS
So while you can use IP or server name - it is often more reliable to use the IP address, but that does NOT get you off the hook from having to specify the sql instance you connect to. Again, previous editions of sql server often allowed a "default" instance, and you did not in general have to specify the "instance", but now you do. And to be double clear, when using such a instance, that sql server needs to be running the sql browser service. (in fact, the browser service is what translates the incoming request to the given and correct instance of sql server).
I DON'T want the password to be stored in the MSysObjects table,
You don't have to, and in fact should NOT include the uid/password in your connection string. And in fact ZERO reason exists to do so.
What you do is execute a one time logon, and THEN link the tables without UID/password. This is not only a great idea, but it also means that your uid/password is not included in the connection strings, but also means users can't get at, or even by accident see/get the uid/password.
It also means that say someone where to launch a copy of access, and import the linked tables from this applcation. When they attempt to use the linked tables, they will NOT work.
So, then how do linked tables work without a password? (and this ALSO by the way saves you from having to re-link tables on startup!!!).
The way this works, is you in code execute a one time logon to the server on startup. That means you can either:
Prompt the user for their sql UID/password.
or
Have in code, the uid/password. (or perhaps in a text file y ou read on startup. You can thus hide, or encrypt or whatever for that uid/passwords.
Then in your startup code, you execute a one time logon. Once you done this, then all linked tables will now work - and work without having uid/password.
since you have two servers then you need to execute two logons, one for server A, and one for server B. But, once again, as long as the linked tables exist, then they will work.
Now, there are "longer" articles on how to use this logon idea, and then not have to include, or re-link your tables for the SQL uid/password.
The basic code to execute a logon is like this:
Function TestLogin(strCon As String) As Boolean
On Error GoTo TestError
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Set dbs = CurrentDb()
Set qdf = dbs.CreateQueryDef("")
qdf.connect = strCon
qdf.ReturnsRecords = False
'Any VALID SQL statement that runs on server will work below.
' this does assume user has enough rights to query built in
' system tables
qdf.sql = "SELECT 1 "
qdf.Execute
TestLogin = True
Exit Function
TestError:
TestLogin = False
Exit Function
End Function
Keep in mind, that ONCE you acheived a legal logon, then EVEN addtional logon attempts will return true.
Not usually a big deal, but this means you supply a valid connection to above, and if it logs on and works - then now all your linked tables (without uid/password) will work.
I note the above issue that ONCE you done the logon, then all 2nd or more times running the above will work (even if bad or incorrect!!! - DO NOT forget this tip!!!). (this can confuse the daylights out of a developer, since they execute logon, (or open a table). Then they test above routine with a BAD uid/passwords, and it works!!!
So, you have to EXIT access to clear out the password cache - no other way.
So, keep the above tips in mind.

VBScript Error Trying to disable dynamic port in SQL Server

I've been trying to automate disabling dynamic ports in a new installation of SQL Server 2012 and setting a static TCP port. I can do this without an issue from the SQL Configuration Manager, but getting a script to do this is giving me more trouble. Luckily, I found someone that was looking to do the exact same thing here: MSDN Forums.
The code I'm using is the following:
Private Function setProperty ( ByVal path, ByVal value )
Set obj = GetObject(path)
errornumber = obj.SetStringValue(value)
If Not errornumber = 0 Then
WScript.Quit(errornumber)
End If
End Function
Set args = WScript.Arguments
If Not args.Count = 1 Then
WScript.Echo "ERROR: Invalid arguments"
WScript.Echo "Usage: cscript " & WScript.ScriptName & " "
WScript.Quit(255)
End If
' set TCP/IP port of SQLServer instance 'SQLSERVER_MATRIX'
setProperty "WINMGMTS:\\.\root\Microsoft\SqlServer\ComputerManagement:ServerNetworkProtocolProperty.InstanceName='SQLSERVER_MATRIX',IPAddressName='IPAll',PropertyName='TcpPort',PropertyType=1,ProtocolName='Tcp'", args(0)
' switch off dynamic ports
setProperty "WINMGMTS:\\.\root\Microsoft\SqlServer\ComputerManagement:ServerNetworkProtocolProperty.InstanceName='SQLSERVER_MATRIX',IPAddressName='IPAll',PropertyName='TcpDynamicPorts',PropertyType=1,ProtocolName='Tcp'", ""
I try running it as suggested on the site with
cscript.exe //nologo set_port_property.vbs
and get the error:
set_port_property.vbs(1,1) (null): 0x8004100E
So that's giving me a namespace error and this is where I'm stuck. It doesn't look like anyone else is having issues with this file as I've found it in multiple places, but I'm trying this on a Windows 10 computer with SQL Server 2012 and everything I found was using 2008 and at most Windows 8. There's a Scriptomatic 2.0 tool that may help, but the link on Microsoft's page is broken so I don't know where to go from here.
The error code as you point out is
WBEM_E_INVALID_NAMESPACE (0x8004100E)
The specified namespace did not exist on the server.
Which is pretty self explanatory, basically the namespace being passed is not recognised for whatever reason, usually it's just incorrectly typed but as you have already mentioned others are using this script without issue.
Couple of suggestions
This likely points to the machine, the first thing I would try is running the script on another machine to see if it can be isolated to this machine alone.
You may also want to test the health of the WMI installation using the in-built tools provided in Windows. The wbemtest.exe tool is a great little tool for testing connection to and query WMI respositories.
Stumbled on the Answer
In the process of answering this question think I may have stumbled on the answer.
Tried suggestion 2. myself to test connecting to
root\microsoft\sqlserver\computermanagement
but failed with the same error using wbemtest.exe but found I could connect to
root\microsoft\sqlserver
After a quick google found the MSDN documentation that describes"How to: Access WMI Provider for Configuration Management using WQL" pointed me in the right direction.
You see the namespaces are different for later versions of SQL Server.
SQL Server 2005
root\Microsoft\SqlServer\ComputerManagement
SQL Server 2008 R2
root\Microsoft\SqlServer\ComputerManagement10
SQL Server 2012, SQL Server 2014, SQL Server 2016#
root\Microsoft\SqlServer\ComputerManagement11
# - Possibly subject to change
After connecting to
root\Microsoft\SqlServer\ComputerManagement11
using wbemtest.exe I no longer received the error and was able to browse classes and instances.
With that in mind changing your namespace in the code should fix the issue.
' set TCP/IP port of SQLServer instance 'SQLSERVER_MATRIX'
setProperty "WINMGMTS:\\.\root\Microsoft\SqlServer\ComputerManagement11:ServerNetworkProtocolProperty.InstanceName='SQLSERVER_MATRIX',IPAddressName='IPAll',PropertyName='TcpPort',PropertyType=1,ProtocolName='Tcp'", args(0)
' switch off dynamic ports
setProperty "WINMGMTS:\\.\root\Microsoft\SqlServer\ComputerManagement11:ServerNetworkProtocolProperty.InstanceName='SQLSERVER_MATRIX',IPAddressName='IPAll',PropertyName='TcpDynamicPorts',PropertyType=1,ProtocolName='Tcp'", ""
In fact at the very bottom of that thread on MSDN someone even hints at this but for SQL Server 2008
Goozak posted in MSDN Forums - silent install with fixed tcp port
Date: Wednesday, March 17, 2010 3:13 PM
"know this is an old thread, but since this is the post I found that helped me solve my problem, I just want to add that for SQL Server 2008 Express, you need to use ComputerManagement10 :ServerNetworkProtocolProperty..."

file share error if Sql Compact 4 in windows application

I am sorry but I want a final answer about that.
First I used SQL compact 3.5 for long time and it take from me long time to make tables and it is work good per one user application but now I have customer who want to run my soft on 8 computer by local network so I said ok then I try to share data file .sdf on server and use it but I get an error I don't remember it so I am searched on the internet and I saw that I must update to SQL compact 4 so update it and after that I get this Stupid error
I can’t Believe that this data don't support this type of use and it take too long time to make tables and other things on SQL compact database and the my customer will not wait me so what is the Reason
My SQL statement is this:
dt = New SqlCeConnection("Data Source=" & dpaa & "\MoveData.sdf;Encrypt Database=True;Password=123cdswdaas;File Mode=Read Write;Persist Security Info=False")
I think that previous answer is slightly misleading - you are definitely able use SQL Server CE 4.0 with database file located on network share. In fact, I am using this functionality in one of my active projects right now. "File Mode=Exclusive" parameter is not necessary - exclusive mode is the only available mode in such case.
The major drawback of this approach is that only one client is able to read from or write to database file at a given time, due to exclusive locking of entire SDF file. But there a circumstances when it is not possible to have full-featured SQL server in your environment (domain policy etc.). In such case shared database file is the only solution available.
Accessing SQL Compact database .sdf file on a network share by multiple users is not supported. You should use SQL Server Express edition for this. There are also multiple posts on stackoverflow on this subject. The version 3.5 supports opening .sdf file exclusively from a network share but 4.0 does not. But no SQL CE version supports shared access of multiple network users to 1 .sdf file.
But upgrading your application to support both SQL Express and SQL Compact databases could be relatively easy task. It depends on how your application access data. For example using Entity Framework your queries could be generated depending on your actual database connection.
You can also use generic classes DbConnection, DbCommand etc. instead of SqlCeConnection, SqlCeCommand etc. - thus you can change used database type without having to maintain two separate versions of your project.
Download SQL Express 2014 with Tools SQLEXPRWT http://msdn.microsoft.com/cs-cz/evalcenter/dn434042.aspx. (You can eventually use also older versions e.g. 2008) SQL Server has a lot more SQL features and data types than SQL CE, so watch that you use only stuff that is compatible with SQL CE.
In your app.config have you can have two connection strings:
<add name="CompactDBConnection" connectionString="data source=|DataDirectory|\CE.sdf; password=xxxxxx; SSCE:Max Buffer Size=16384; temp file max size=256; ssce:autoshrink threshold=100; ssce:max database size=4091" providerName="System.Data.SqlServerCe.4.0" />
<add name="ExpressDBConnection" connectionString="Server=myServerName\myInstanceName;Database=myDataBase;User Id=myUsername; Password=myPassword;" providerName="System.Data.SqlClient" />
You can chose then which one to use at the app startup
For creating DbConnection check this C# Retrieving correct DbConnection object by connection string.
Here is a small example of calling stored procedure using DbCommand instead of SqlCeCommand:
DbConnection dbConn = GetConnection(connStr);
DbProviderFactory sqlF = DbProviderFactories.GetFactory(dbConn);
using (DbCommand b2bcmd = sqlF.CreateCommand())
{
DbParameter msg = sqlF.CreateParameter();
msg.ParameterName = "#errorMessage";
msg.Direction = ParameterDirection.Output;
msg.DbType = DbType.String;
msg.Value = string.Empty;
msg.Size = 2048;
b2bcmd.Connection = dbConn;
b2bcmd.CommandType = CommandType.StoredProcedure;
b2bcmd.CommandText = "PB2BImport";
b2bcmd.Parameters.Add(msg);
b2bcmd.ExecuteNonQuery();
result = Convert.IsDBNull(msg.Value) ? "N/A" : (string)msg.Value;
}
I presume you do not use Entity framework - but it would be much easier with it.

Script to replicate SQL Server data dynamicaly

I have an access 2010 application with a SQL Server database.
But I need to do an offline version. So I thought I would create a local SQL Server database on their computers then they can run a script to update their data before they go on the road.
NOTE: There won't be any sync. The data in offline mode is only for read-only and any changes will be lost.
I tried with Management Studio like this:
But I realized that the data is hard coded instead of doing inserts from selects.
Is there any easy way to create the script?
What I have so far is my pass through query in access to create the backup of my online database.
Then I have my pass through query to restore the backup to the local server.
The only problem is how can I build the connection string for the second query. It's currently set to this one
ODBC;DRIVER=SQL Server;SERVER=010-068\SQLEXPRESS;UID=marcAndreL;Trusted_Connection=Yes;DATABASE=SMD
but because it's a different database for everyone, it won't work.
How can we build a custom connection string?
I am using SQL Server Express 2012 and Windows Authentication, so using the answer provided here, I find this works for me:
Sub TestCon()
Dim cn As New ADODB.Connection
cn.Open ServerConLocal
End Sub
Function ServerConLocal()
''OleDB Connection
ServerConLocal = "Provider=sqloledb;Data Source=localhost\SQLEXPRESS;" _
& "Initial Catalog=Test;Integrated Security=SSPI;"
End Function
For an ODBC connection string in a Pass-through query, this works for me:
ODBC;Driver={SQL Server Native Client 11.0};Server=localhost\SQLEXPRESS;Database=test;
Trusted_Connection=yes;
Take a look at download-only articles for merge replication. MSDN.

Smo does not show 2008 SQL Server instances when 2005 instances exist

I am trying to enumerate all SQL Server instances installed on a local machine. I am using SmoApplication.EnumAvailableSqlServers(true). However, only SQL Server Express 2005 instances are shown. Default 2008 instance is not shown at all!
I tried 2 other solutions with SqlServerRegistrations.EnumRegisteredServers() and SqlDataSourceEnumerator.Instance.GetDataSources() but they do not work either.
There is another question regarding this (Can't enumerate SQL Server 2008 Registered Servers with SMO) but it unfortunately has no answer.
Found the solution to your problem here
Solution: Explicitly set the ProviderArchitecture property to the architecture of the target SQL Server.
If you do not explicitly set the ProviderArchitecture property, it will assume that of the running process. If the host process of your application does not match the architecture of the installed version of SQL Server on the target server, the ServerInstances collection will be empty. This is due to the separate x86 and x64 WMI providers and how SQL Server registers instances.
Try
Dim objManagedComputer As New ManagedComputer("target_servername")
objManagedComputer.ConnectionSettings.ProviderArchitecture = ProviderArchitecture.Use64bit
Dim objServerInstance As ServerInstance
For Each objServerInstance In objManagedComputer.ServerInstances
MsgBox(objServerInstance.Name)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
Here's another alternative you could try using the ManagedComputer Class (Namespace: Microsoft.SqlServer.Management.Smo.Wmi).
ManagedComputer mc = new ManagedComputer();
foreach (ServerInstance si in mc.ServerInstances)
{
Console.WriteLine(si.Name);
}

Resources