Connection Code:
set conx = Server.CreateObject("ADODB.connection")
conx.Open Application("connectionString")
set cmdx = server.CreateObject("ADODB.command")
cmdx.ActiveConnection = conx
cmdx.CommandText = "dbo.sproc"
cmdx.CommandType = &H0004
set rsx = Server.CreateObject("ADODB.Recordset")
rsx.open cmdx
resarray = rsx.getrows
This connection string works:
connectionString = "DRIVER=SQL Server;UID=User;Address=000.000.000.000;Network=DBMSSOCN;DATABASE=Database;SERVER=server;Password=password;"
This doesn't...
connectionString = "Provider=SQLOLEDB;Data Source=000.000.000.000;UID=User;Address=000.000.000.000;Network=DBMSSOCN;DATABASE=Database;SERVER=server;Password=password;"
The error I get is:
ADODB.Recordset error '800a0e78'
Operation is not allowed when the object is closed.
What am I missing?
Just a punt here, but the way OLEDB drivers handle Row count informationals differs from ODBC.
I very much suspect that if you add SET NOCOUNT ON at the top of the Stored Procedure the problem will go away.
Sounds like a permissions problem in the database!
Related
I am newbie in VBScript and I've come across with the following problem. I want get data from sql server db and to allow RecordCount properties. Next code get data but RecordCount is disabled. How can I enable this properties
Const DB_CONNECT_STRING = "Provider=SQLOLEDB.1;Data Source=BUG\SQLSERVER2005;Initial Catalog=test;user id ='sa';password='111111'"
Set myConn = CreateObject("ADODB.Connection")
Set myCommand = CreateObject("ADODB.Command" )
myConn.Open DB_CONNECT_STRING
Set myCommand.ActiveConnection = myConn
myCommand.CommandText = ("select * from klienci k where k.indeks = " & oferty(16))
Set klienci = myCommand.Execute
AFAIK you can't change the cursor type when using the Execute method of the Command object, and you can't change the cursor type after you retrieved the recordset. Something like this might work, though:
Const DB_CONNECT_STRING = "Provider=SQLOLEDB.1;Data Source=BUG\SQLSERVER2005;Initial Catalog=test;user id ='sa';password='111111'"
Set myConn = CreateObject("ADODB.Connection")
myConn.Open DB_CONNECT_STRING
query = "select * from klienci k where k.indeks = " & oferty(16)
Set klienci = CreateObject("ADODB.Recordset")
klienci.CursorLocation = 3 'adUseClient
klienci.CursorType = 3 'adOpenStatic
klienci.LockType = 1 'adLockReadOnly
klienci.Open query, myConn
I don't think this is a VBScript issue- I think it is an ADO issue.
I think you are using a default forward-only cursor which won't work with recordcount.
I think you should stick a cursortype=adOpenStatic in there but I'm having a little trouble determining if you are specifying a recordset object - klienci?
If so try
klienci.cursortype=adOpenStatic
I cant get dns less connection to Ms Access db to work here the code.
In the dbconnection.asp file is this
Dim MM_IMT_STRING
''MM_IMT_STRING = "dsn=EDA;"
MM_IMT_STRING =("Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\inetpub\wwwroot\essel\Connections\EDA.mdb")
and in the default.asp is this
<!--#include file="Connections/dbconnection.asp" -->
Dim CHANNEL
Dim CHANNEL_numRows
Set CHANNEL = Server.CreateObject("ADODB.Recordset")
CHANNEL.ActiveConnection = MM_IMT_STRING
I have been struggling with this issue for days now, if someone know why its not linking up please tell me thanks.
Where is your Connection object created?
I'm missing something like
Set objConnMDB = Server.CreateObject("ADODB.Connection")
objConnMDB.ConnectionString = MM_IMT_STRING
objConnMDB.Open
CHANNEL.ActiveConnection = objConnMDB
' // do your stuff here '
objConnMDB.Close
Set objConnMDB = Nothing
I want to simply retrieve a single record from a database in a classic ASP page. The code below basically works, but there are a couple problems I need help solving:
1) I want to see if a record was returned or not. result is not Nothing, so the redirect at the bottom is never performed. contact.RecordCount always returns -1, so I apparently can't use that either. Oddly, trying to access RecordCount outside the function throws an "Object doesn't support this property or method: 'RecordCount'" error.
2) I've read about disconnected queries and have seen examples where the connection and command are closed and/or set to Nothing at the end of the function. Is there a definitive best practice on what I should do?
3) Will using a parameterized query fully protect me from SQL injection, or do I need to manually remove dangerous words and characters?
function GetContactByUsername(username)
Dim conn, command, param, contact
set conn = server.CreateObject("adodb.connection")
conn.Open Application("DatabaseConnectionString")
Set command = Server.CreateObject("ADODB.COMMAND")
set command.ActiveConnection = conn
command.CommandType = adCmdText
command.CommandText = "Select * from MY_DATABASE.dbo.Contact where Username = ?"
Set param = command.CreateParameter ("Username", adVarWChar, adParamInput, 50)
param.value = username
command.Parameters.Append param
Set contact = Server.CreateObject("ADODB.RECORDSET")
contact.Open command
Response.Write contact.RecordCount '' always -1
set GetContactByPurlCode = contact
end function
dim result
result = GetContactByUsername(Request.QueryString("username"))
if result is Nothing then '' never true
Response.Redirect "/notfound.asp"
end if
FirstName = Trim(result("FirstName"))
LastName = Trim(result("LastName "))
1) To check for a lack of records, use rs.EOF, not "Is Nothing." The RecordSet object is always an object. It's just that sometimes it doesn't have any rows.
If you want to use RecordCount but are getting -1, then switch to a client-side cursor (adUseClient).
2) No definitive best-practice here, but I've personally always closed the Connection and Command, and have not had much in the way of performance problems. Connection objects are particularly precious, so close them as early as possible on high volume pages.
3) Yes, parameterizing your variable is perfect, unless you are calling a stored procedure that constructs a dynamic query.
By the way, you should avoid "SELECT *" as that will cause you to return more data than needed and is a maintenance problem waiting to happen.
I've created an XML file using the .Save() method of an ADODB recordset in the following manner.
dim res
dim objXML: Set objXML = Server.CreateObject("MSXML2.DOMDocument")
'This returns an ADODB recordset
set res = ExecuteReader("SELECT * from some_table)
With res
Call .Save(objXML, 1)
Call .Close()
End With
Set res = nothing
Let's assume that the XML generated above then gets saved to a file.
I'm able to read the XML back into a recordset like this:
dim res : set res = Server.CreateObject("ADODB.recordset")
res.open server.mappath("/admin/tbl_some_table.xml")
And I can loop over the records without any problem.
However what I really want to do is save all of the data in res to a table in a completely different database. We can assume that some_table already exists in this other database and has the exact same structure as the table I originally queried to make the XML.
I started by creating a new recordset and using AddNew to add all of the rows from res to the new recordset
dim outRes : set outRes = Server.CreateObject("ADODB.recordset")
dim outConn : set outConn = Server.CreateObject("ADODB.Connection")
dim testConnStr : testConnStr = "DRIVER={SQL Server};SERVER=dev-windows\sql2000;UID=myuser;PWD=mypass;DATABASE=Testing"
outConn.open testConnStr
outRes.activeconnection = outConn
outRes.cursortype = adOpenDynamic
outRes.locktype = adLockOptimistic
outRes.source = "product_accessories"
outRes.open
while not res.eof
outRes.addnew
for i=0 to res.fields.count-1
outRes(res.fields(i).name) = res(res.fields(i).name)
next
outRes.movefirst
res.movenext
wend
outRes.updatebatch
But this bombs the first time I try to assign the value from res to outRes.
Microsoft OLE DB Provider for ODBC Drivers error '80040e21'
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.
Can someone tell me what I'm doing wrong or suggest a better way for me to copy the data loaded from XML to a different database?
Update, partly solved
So it turns out that my error is caused by my attempting to set the value of an Identity field. If I temporarily change that field to not be an Identity, all of the data gets inserted perfectly.
Now a followup question
How can I temporarily turn off the Identity property of that field, then turn it back on when I'm done with my updates?
I was never able to get Recordset.AddNew to work because of the above problem.
As a workaround, I'm doing a SET IDENTITY_INSERT table ON, executing the INSERT sql, and SET IDENTITY_INSERT table OFF.
After reading the XML back, set the connection property of the recordset to the new database connection and then invoke UpdateBatch.
I am doing some calculation with the data set I take from my database. Null values give errors so I tried replacing null values with zeros(0). Here is the error I get,
ADODB.Recordset error '800a0cb3'
Current Recordset does not support
updating. This may be a limitation of
the provider, or of the selected
locktype.
Never seen it before. Here is my code.
If IsNull(objRevenueToday("REVENUE")) Then
objRevenueToday("REVENUE") = 0
End If
Your recordset appears to be read-only. There could be a number of reasons for this; you're reading a view that contains a Group By clause, you don't have permissions, etc.
Using the syntax Set Recordset = Command.Execute always opens a read only cursor. What you need to do is open the cursor using the Recordset object. The Source parameter of the Open method is your Command object. This allows you to set the desired location and locktype.
Dim cmdProc as ADODB.Command
Dim rsData as ADODB.Recordset
Set cmdProc = New ADODB.Command
With cmdProc
Set .ActiveConnection = SomeConnection
.CommandType = adCmdStoredProc
.CommandText = "selCustomer"
' ... Create parameters
End With
Set rsData as New ADODB.Recordset
rsData.Open cmdProc,, adOpenStatic,adLockBatchOptimistic
'...Process recordset data.
Here is the solution:
If IsNull(objRevenueToday("REVENUE")) Then
RevenueToday = "0"
Else
RevenueToday = objRevenueToday("REVENUE")
End If
Not very ideal but fixed my error.
Assuming SQL Server (although similar techniques available in other DBs.
Change the query so that is will not return nulls in records. For example in the T-SQL
SELECT ISNULL(REVENUE, 0), .... FROM ....
Change the settings as below. It force the client side cursor...It worked for me
set pagedlistrs=CreateObject("adodb.recordset")
pagedlistrs.cursorlocation = 3 ' adUseClientpagedlistrs
pagedlistrs.Open SQL, objConn, 3,3,1