Classic ASP ADODB results corrupted [closed] - sql-server

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
I am migrating a Classic ASP application to a newer SQL Server database server.
The new server is a Windows 2019 Server (version 10.0.17763). I have an ADODB connection (version 10.0) to the SQL Server 2019 database (database is migrated from an older version).
It seems that the application runs almost perfectly, but among the dozens of ADODB queries that work fine is one that returns corrupted data.
UPDATED: It turns out that the only columns affected are indeed nvarchar(max) columns. As such, this is a duplicate of this question. My original question's detail follows:
If I run the stored procedure in SQL Management Studio, the results are perfect:
SELECT dbo.[Staff.Reports].[Report Title], replace(dbo.[Staff.Reports].[Description],char(34),'') as RepDesc
FROM dbo.[Staff.Reports] LEFT OUTER JOIN dbo.[Staff.Reports Permissions] ON dbo.[Staff.Reports].[Report ID] = dbo.[Staff.Reports Permissions].[Report ID]
WHERE dbo.[Staff.Reports Permissions].[Staff ID] = #StaffID
Returns:
Report Title
RepDesc
Achievements Admin
Update OAA, and other Achievements
AdRef By Engineers
AdRef By Engineers
Adref Status Count
Ad Campaign report by ref no.
etc.
However, when the identical query is run through the Classic ASP code, using the ADODB connection, the data returned becomes corrupted:
Report Title
RepDesc
Achievements Admin
] 0
AdRef By Engineers
Adref Status Count
0
Out of interest, the description column is an nvarchar(max) type. I established the content of the output by logging it to a text output file - it's not an issue with the display of the data.
The output is the same number of characters, but they are mostly null and control characters.
I have tried deleting and recreating the query, but am at a loss as to what is happening.
Can anyone help, please?
Thanks for your interest, AlwaysLearning. All queries are run using the same 'GetRecordset' function, which is basically:
Set oConnection = CreateObject("ADODB.Connection")
oConnection.Open "Data Source=TheDatabase;UID=Fred;Password=" & strPassword
oConnection.CursorLocation = 3
Set CreateConnection = oConnection
Set objComm = Server.CreateObject("ADODB.Command")
objComm.ActiveConnection = CreateConnection
objComm.CommandType = adCmdStoredProc
objComm.CommandText = cQuery
objComm.CommandTimeout = 1800
For iThisParameter = 1 to UBound(aParameters)
Set objParam = objComm.CreateParameter("#par" & iThisParameter, adVarChar, adParamInput, 1024)
objComm.Parameters.Append objParam
objComm.Parameters("#par" & iThisParameter) = aParameters(iThisParameter)
Next
Set GetRecordset = objComm.Execute

You should use the modern, supported driver for ADO to connect to SQL Server.
Using ADO with OLE DB Driver for SQL Server

Related

MS Access DB front end SQL Server Back End Unable to Open any form as New Record after table migration

I have similar issue to one previously posted but none of the answers helped.
I cannot open any form in my DB to a new record.
This all worked before moving tables from Access DB to SQL Server and linking back to them.
All tables have an ID column of datatype integer set as primary key on the server.
All tables have a RowVersion column of datatype datestamp.
All forms are based on a single table as record source.
All columns of datatype = bit have default value set to 0 on the SQL Server.
In Access form, properties are set to allow additions = yes, allow edits = yes, I also set data entry = yes as well which wasn't necessary before SQL server hosted the tables but it didn't help anyway.
I tried on button click event that opens the form:
Private Sub OpenFormNameBtn_Click()
DoCmd.OpenForm "FormName", , , "[CustID]=" & Me![CustID] & " AND [EnvID]= '" & Me![EnvID] & "'"
Forms!DeploymentsF.Form.AllowAdditions = False
Forms!DeploymentsF.Form.AllowAdditions = True
DoCmd.GoToRecord , , acNewRec
End Sub
NOTE: the criteria of custid and envId worked when the tables were in access and I need them to stay this way.
The above caused the auto number ID to appear on the form for an instant but then it disappeared just as quickly! In the code behind the submit button at the bottom of the form (to write the record to the table), it errors out and I see where the Form's ID field = Null in debug so it couldn't write the id in the update statement to the table. I CAN, however, insert a record into the table with a query insert statement on the SQL server no problem AND I can edit records in forms and sub forms and it writes to the tables on the SQL Server.
I also tried a simple form with no criteria and no pre-filling and got the error, "Can't go to the specified record"
I tried button click event: DoCmd.OpenForm "FormName", , , , acFormAdd.
Anyone seen this before and have a solution? I'm out of ideas.

QSqlQuery Selects Deleted Table

I have a QT application and I am showing the user some data from ms sql database which is related to selected ID from comboBox object. My problem is, I've deleted all my tables on my ms sql server but my qt application still finds tables. Here is my sample code :
QString query = 'SELECT Date FROM [dbo].[Parametre] WHERE id=';
QString selected_item = this->ui->comboBox->currentText();
query.append(selected_item);
QSqlQuery qry;
if(qry.exec(query))
{
this->listWidget->addItem->qry.value(0).toString();
}
else
{
qDebug()<<qry.lastError();
}
There's no valid table in my ms sql database but it still writes deleted Date's on my listWidget object. My question is what causes this problem and how can I solve this?
I didn't close my database connection on my previous version on my application. I changed this and now I am closing my connection via exit button and my problem solved. For those have same problem try to close your database connection and open new connection everytime you run your application. If you did not do this qt forces sql to close connection and this causes some problems.

Insert on linked table (from MS Access to SQL Server) fails because of field length

I'm trying to do an append query from MS Access into SQL server. The SQL server column is varchar(max) which I thought meant it can accept more than 4000 characters
I get the following error when running this query from VBA in MS Access
Run Time Error 3155 ODBC - insert on a linked table
failed [Microsoft] [SQL Server Native Client 10.0] {SQL Server] The
size (7596) given to the parameter '#P6' exceeds the maximum allowed
(4000). (#2717)
adding my queries
this query is based on an linked outlook folder, Deleted Items
SELECT Trim(Mid([contents],InStr([contents],"Short Description: ")+19,(InStr([contents],"Requestor: ")-1)-(InStr([contents],"Short Description: ")+19)-3)) AS ShortDesc, Trim(Mid([contents],InStr([contents],"Requestor: ")+10,(InStr([contents],"Requestor EMail: ")-1)-(InStr([contents],"Requestor: ")+10)-3)) AS Requester, Trim(Mid(Mid([contents],InStr([contents],"Office Location: ")+3),InStr(Mid([contents],InStr([contents],"Office Location: ")),"Description:")+13,(InStr(Mid([contents],InStr([contents],"Office Location: ")),"Assigned Task: ")-1)-(InStr(Mid([contents],InStr([contents],"Office Location: ")),"Description:")+13)-3)) AS Description, Trim(Mid([contents],InStr([contents],"Request Item: ")+14,12)) AS TicketNoText, Val(Mid([contents],InStr([contents],"Request Item: ")+19,7)) AS TicketNo, Val(Mid([contents],InStr([contents],"Assigned Task: ")+19,7)) AS TaskNo, Mid([contents],InStr([contents],"Delivery Date: ")+15,10) AS DeliveryDate, Trim(Mid([contents],InStr([contents],"Requestor EMail: ")+17,(InStr([contents],"Office Location: ")-1)-(InStr([contents],"Requestor EMail: ")+17)-3)) AS RequesterEMail
FROM [Deleted Items]
WHERE ((([Deleted Items].From)="xxxxxxx#service-now.com") AND (([Deleted Items].Subject)="you just assigned a ticket to yourself"));
then, the append query is based on this one and a few other ones
INSERT INTO PROJECTS ( TaskNo, RequesterID, Description, TicketNo, ProjectFolderLink, SNLink, OpenedOn, DateDue )
SELECT QSNNew.taskno, cmbRequesters.RequesterID, "SHORT DESCRIPTION: " & [shortdesc] & Chr(13) & Chr(10) & Chr(13) & Chr(10) & "DESCRIPTION: " & [Description] AS Expr4, QSNNew.TicketNo, "#\\link to a network folder" & lpad([ticketno],"0",7) & "\#" AS Expr1, "#https://xxxx.service-now.com/nav_to.do?uri=sc_task.do?sysparm_query=number=TASK" & lpad([taskno],"0",7) & "#" AS Expr2, Now() AS Expr3, Mid([DeliveryDate],6,2) & "/" & Right([DeliveryDate],2) & "/" & Left([DeliveryDate],4) AS Expr5
FROM (QSNNew LEFT JOIN PROJECTS ON QSNNew.TicketNo = PROJECTS.TicketNo) LEFT JOIN cmbRequesters ON QSNNew.[Requester] = cmbRequesters.RequesterName
WHERE (((PROJECTS.TicketNo) Is Null));
in case anyone is wondering what I'm doing, I'm loading tickets from Service Now into an Access database and there's no other way of doing it, other than parsing notification emails i get from Service Now when a ticket is assigned to me.
So I'm parsing those emails and creating my own version with links to the ServiceNow page, network folders for the ticket, etc.
It's a matter of driver (SQL Native Client and ODBC Driver 17 are limited to 4000 chars). If you use SQL Server Driver (10.09.18362.01) limit is 64000 chars.
As yu2 suggested ADODB query would avoid that (ODBC Passthrough should do it too).
The parameter #P6 is produced by ODBC see Optimizing Microsoft Office Access Applications Linked to SQL Server Understanding Dynasets
This is answer for your question
3155 Insert into Linked Table error
On this link Microsoft recommends to use ADODB instead of ODBC if you can't decrease field size in application.
ODBC protocol is generally for big data -- sql server -- which uses "Fire Hose" bandwith. Access uses (my term) garden hose bandwith (with all due respect for mini RDBMSs) because Access is basically a mini RDBMS (relational database management system) which is also file based. Unless everything (front/back ends) is set up perfectly and conditions are ideal -- you will encounter the problem you are having. Microsoft came up with ADODB as a workaround for this problem. When I have to interface between sql server and Access -- I use ADODB. This has proven to be much more reliable and consistent between the small and large RDBMSs. Here is some sample ADODB code for reading from and writing to a Sql Server from Access
'--add a reference in Tools/References to Microsoft ActiveX Data Objects 2.x Library '--(2.5 or higher)
...
The Access "Long Text" column can contain a text string up to a gigabyte in size. The message says you are trying to fit 7596 characters into a 4000 character field.
If so, your SQL server database should be exposing an ODBC LongVarChar column instead of VarChar.
LongVarChar is an ODBC type. The mapping is done by the ODBC driver. If you use an ODBC driver that maps VarChar(MAX) to a VarChar ODBC column, you can either get a different driver, or, possibly, use a SQL SERVER 'TEXT' column instead. TEXT is the old SQL Server column type, from when VarChar could only go to 4000. Old ODBC drivers recognize that TEXT columns map to LongVarChar.
I think the error message is quite helpful.
You are trying to fit a string with length of 7596 while your maximum varchar length is 4000.
I guess you either truncate it or store it as a blob.

"The column cannot be modified because it is an identity, rowversion or a system column" - but it isn't

I am getting this error:
The column cannot be modified because it is an identity, rowversion or
a system column. [Column name = BatchClosed]
But [BatchClosed] is a nullable bit column and identity is false.
I am using Sql Server Compact Edition and the table is used in merge replication.
There are system columns ( _sysIG, _sysCG, _sysCD, _sysP1, _sysMC, _sysMCS, _sysSR) and a rowguid for the purpose of replication in the table.
The table is not marked as download-only in the publication.
The table is filtered though, and the BatchClosed field is used as a part of that filter:
WHERE surveyorid = convert(int, HOST_NAME()) AND BatchClosed = 0
When I test it in Management Studio connected to the Sql Server CE database with this sql I get the same error
UPDATE tblBatch SET BatchClosed = 0 WHERE BatchClosed = 1 AND SurveyID = 160;
Interestingly, this sql would not actually do an update because there are no records with BatchClosed = 1. (I assume that's just something to do with the way Sql Server CE works)
NB the test sql will work in Sql Server 2008 R2 but not on the Sql Server CE version after synchronization
EDIT
If I try to update any column in that table I get the same error message - as if all columns are system columns, not just the one in the filter
EDIT 2
I checked my installation and noted that the server tools had an older installation date while the x64 version was at SP1:
So I un-installed the x64 components, then downloaded and installed the server tools. It now looks like this:
I immediately lost my web synchronization. It took me a painful day of working through various dead ends before I found out how to get that back. (Solution here: Configuring Web Synchronization for Merge Replication to Sql Server CE)
Result? Still get the same error. :-(
I can both delete and insert in the table in question, and also update like this:
-- Script Date: 05-07-2014 09:26 - ErikEJ.SqlCeScripting version 3.5.2.39
UPDATE [tblBatch]
SET [SamplePercentage] = 0
WHERE BatchId = 2;
GO
I think you cannot update any other columns, as they are either system controlled (PK or rowguid) or participate in join filters in the publication. But to do updates, you can do a DELETE followed by an INSERT.

Import de-normalized relational data from Excel into SQL Server [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I need to import data from an Excel spreadsheet into SQL Server, but the data isn't in a relational/normalized format so the import wizard isn't going to cut it (as far as I know).
The data is in this format:
Category SubCategory Name Description
Category#1 SubCategory#1 Product#1 Description#1
Category#1 SubCategory#1 Product#2 Description#2
Category#1 SubCategory#2 Product#3 Description#3
Category#1 SubCategory#2 Product#4 Description#4
Category#2 SubCategory#3 Product#5 Description#5
(apologies I'm lacking the inventiveness to come up with 'real' data at this time in the morning...)
Each row contains a unique product, but the cateogry structure is duplicated. I want to import this data into three tables:
Category
SubCategory
Product
(I know SubCategory should really be contained within Category, DB was not my design)
I need a way to import unique rows based on the Category and then SubCategory columns, and then when importing the other columns into Product, obtain a reference to the SubCategory based on name.
Short of scripting this, is there any way to do it using the import wizard or some other tool?
I had a similar problem a while ago, and did not find any easy way to do this using an import wizard. The way I resolved the import (as this was a one-off task, and not something that was going to hang around) was to create a simple macro (VBA) from excel that would simply call a stored proc, using each row as the parameters.
The stored proc would intelligently insert each parameter (column), and then grab the ID to use as the foreign key on the next parameter insert.
For example:
DECLARE #CategoryID INT
DECLARE #SubCategoryID INT
-- Check that the Category exists
IF NOT EXISTS (SELECT * FROM tblCategories WHERE CategoryName = #pCategoryName)
BEGIN
-- Your insert statement here, then grab the ID
SET #CurrencyID = scope_identity()
END
ELSE
BEGIN
-- Set the category ID here
END
The VBA macro had code similar to:
Private Sub CommandButton1_Click()
Dim cnt As ADODB.Connection
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Dim intActiveRow As Long
Dim intInsuranceProduct As Variant
' Get our connection
Set cnt = CreateConnection()
' Read the input sheet
Set wbBook = ActiveWorkbook
Set wsSheet = wbBook.Worksheets(1)
' Ignore the header row
intActiveRow = 2
' process every row into the database
Do While (wsSheet.Cells(intActiveRow, 1) "")
' execute the stored procedure, GenerateScript would create your SQL
cnt.Execute (GenerateScript(wsSheet, intActiveRow))
' increment i for row count
intActiveRow = intActiveRow + 1
Loop
End If
'Cleaning up.
cnt.Close
Set cnt = Nothing
Set wbBook = Nothing
Set wsSheet = Nothing
End Sub
You might want to investigate SSIS (SQL Server Integration Services) formerly known as DTS (Data Transformation Services).
In SSIS there is the ability to use Excel as a data source where you can specify filters and transformations of the data for loading into the appropriate SQL Server tables. It might take a little research but it is a pretty robust tool, and also support the ability to create a Script task if you need to do something not Out of the Box.
Actually a good software to use that was developed specifically for this type of work is Relational Excel - there's a trial edition but it can be used past the trial period it just shows nag screens every once in a while. www.relationalexcel.com
The solution very fast is to use the tool "Analyze Table" in MS Access, your Table will be Normalyze, try!

Resources