PDO DBLib not working - sql-server

I have a connection with the DBLIB PDO driver, and I am not getting any errors on connecting, but when I run a query an exception is thrown with the error below. I have played around with the syntax of the query as well. I am connecting to a MS SQL server:
SQLSTATE[HY000]: General error: 208 General SQL Server error: Check messages from the SQL Server [208] (severity 16) [SELECT PCO_INBOUNDLOG.PHONE FROM PCO_INBOUNDLOG]
The code:
$sql = "SELECT PCO_INBOUNDLOG.PHONE FROM PCO_INBOUNDLOG";
foreach($this->mssql->query($sql) as $row) {
print_r($row);
}
This is the first time I have ever done a query to a MS SQL server so my syntax may be wrong, any ideas?

First, find out what error 208 means:
select * from sys.messages where message_id = 208
Second, check the FROM syntax (including the examples!) and object identifier rules.
Third, write the query correctly:
SELECT PHONE FROM PCO_INBOUNDLOG
Or, probably better (because it's good practice to include the schema name):
SELECT PHONE FROM dbo.PCO_INBOUNDLOG
Or even:
SELECT p.PHONE FROM dbo.PCO_INBOUNDLOG p

Related

T-SQL Openquery - error due to space in the table name

I have the below query that is trying to pull data from Sage 50 pervasive 13 database into SQL server using a link server. I've been able to pull all data from all tables into SQL Server except for this one table because it has a space in the table name.
I've not been successful with anything I've changed it to. Can anyone help me get this query working?
select *
from openquery(ARKSAGE,'select * from NEPHROPATHOLOGYASSO1.Budget Details')
When I change the above query to this:
select *
from openquery(ARKSAGE,'select * from NEPHROPATHOLOGYASSO1.[Budget Details]')
I get this error message:
OLE DB provider "MSDASQL" for linked server "ARKSAGE" returned message "[PSQL][ODBC Client Interface][LNA][PSQL][SQL Engine]Syntax Error: select * from NEPHROPATHOLOGYASSO1.<< ??? >>[Budget Details]".
Msg 7321, Level 16, State 2, Line 61
An error occurred while preparing the query "select * from NEPHROPATHOLOGYASSO1.[Budget Details]" for execution against OLE DB provider "MSDASQL" for linked server "ARKSAGE".
The PSQL in the error message tells me the linked server is probably running Postgresql, rather than SQL Server. Postgresql marks object names with double quotes instead of brackets. Therefore you should try this:
select *
from openquery(ARKSAGE,'select * from NEPHROPATHOLOGYASSO1."Budget Details"')
Additionally, I'm not sure what the << ??? >> text is for, but it looks a little like it's complaining about an odd unicode character in there somewhere. So look out for invisible whitespace. Or maybe it's just part of how the error message is formatted in the context of a linked Postgresql server.

SQL Server throwing error on valid SQL - incorrect syntax near 'and'

I have a data transformation application where one of the first steps is for the user to paste in a valid SELECT statement. After it is verified, the app will execute it against their database and return the schema of the result set. They then tell us what they want us to do with the results.
My problem is that at one customer site, the user pastes in what appears to be a valid SQL statement but SqlCommand is throwing an error. They sent me a screenshot of the error message. The error is 'incorrect syntax near 'and'. However, the SQL statement looks fine to me and runs in SSMS.
The SQL statement is:
select
id_acc,
PaymentOption,
ServiceCatDesc,
ServiceType,
format(c_custlocalstartdate,'MMMyyyy') as mmmyyyy,
sum(c_debitamount) as debitamount,
sum(c_rateusage) as rateusage
from
netmeter..vw_usage_details
where
id_usage_interval in (select id_interval
from t_usage_interval
where id_usage_cycle = 33
and dt_start between dateadd(month, -12, getdate()) and getdate())
group by
id_acc, PaymentOption, ServiceCatDesc, ServiceType,
format(c_custlocalstartdate,'MMMyyyy')
This happens whether the customer is using a SQL Server driver or ODBC (either connecting to the same database).
Any ideas?
The SQL statement is valid and runs outside of the application. A lot of other queries run file in our application. Why is the database throwing a syntax error on this statement?

How to get rid of SQL Profiler exception 208 using table valued parameter (TVP)

I did search for exception 208 (invalid object name) identified by SQL Profiler and found many hints regarding "Deferred Name Resolution". Nevertheless I still did not find an asnwer related to TVP (table valued parameter) and SQL Server 2019.
I´m going to migrate an application from SQL Server 2016 to SQL Server 2019 and I´m wondering why Profiler is starting throwing of hundrets of exceptions per hour with same code. It turned out that all of them are Exception 208 (invalid object name).
Steps for reproduction:
Set compatbility level of database to 140 (2017);
SSMS as well as Profiler runs without any exception.
Set compatbility level of database to 150 (2019);
SSMS runs fine but SQL Profiler throws exception 208 (invalid object name).
Is there any way to get rid of this? If I´m looking for any unexpected exceptions in database I get blind due to that many useless exceptions.
--ALTER DATABASE [...] SET COMPATIBILITY_LEVEL = 140;
ALTER DATABASE [...] SET COMPATIBILITY_LEVEL = 150;
GO
CREATE TYPE dbo.LocationTableType AS TABLE ( LocationName VARCHAR(20) );
GO
DECLARE #LocationTVP AS dbo.LocationTableType;
SELECT * FROM #LocationTVP; -- Throws the exception in profiler
--INSERT INTO #LocationTVP (LocationName) SELECT 'MyLocation'; -- Throws the exception in profiler
GO
DROP TYPE dbo.LocationTableType;
GO
Either INSERT or SELECT statement is throwing an exception. Could anyone let me know how to turn this off in SQL-Server 2019 to be able to further use of SQL profiler.

INSERT failure with SQLAlchemy ORM / SQL Server 2017 - Invalid Object Name

Firstly, I have seen many answers which is specific to the Invalid Object Name error working with SQL Server, but None of them seem to solve my problem. I don't have much idea on SQL Server dialect, but here is my current setup required on the project.
SQL Server 2017
SQLAlchemy (pyodbc+mssql)
Python 3.9
I'm trying to insert a database row, using the SQLAlchemy ORM, but it fails to resolve the schema and table, giving me the error of type
(pyodbc.ProgrammingError) ('42S02', "[42S02] [Microsoft][ODBC Driver
17 for SQL Server][SQL Server]Invalid object name 'agent.dbo.tasks'.
(208) (SQLExecDirectW); [42S02] [Microsoft][ODBC Driver 17 for SQL
Server][SQL Server]Statement(s) could not be prepared. (8180)")
I'm creating a session with the following code.
engine = create_engine(connection_string, pool_size=10, max_overflow=5,
pool_use_lifo=False, pool_pre_ping=True, echo=True, echo_pool=True)
db_session_manager = sessionmaker()
db_session_manager.configure(bind=engine)
session = db_session_manager()
I have a task object defined like
class Task(BaseModel):
__tablename__ = "tasks"
__table_args__ = {"schema": "agent.dbo"}
# .. field defs
I'm trying to fill the object fields and then do the insert like the usual
task = Task()
task.tid = 1
...
session.add(task)
session.commit()
But this fails, with the error mentioned before. I tried to execute a direct query like
session.execute("SELECT * FROM agent.dbo.tasks")
And it returned a result set.
The connection string is a URL object, which prints like
mssql+pyodbc://task-user:******#CRD4E0050L/agent?driver=ODBC+Driver+17+for+SQL+Server
I tried to use the SQL Server Management Studio to insert manually and check, there it shown me a sql dialect with [] as field separators
like
INSERT INTO [dbo].[tasks]
([tid]..
, but SQLAlchemy on echo did not show that, instead it used the one I see in MySQL like
INSERT INTO agent.dbo.tasks (onbase_handle_id,..
What is that I'm doing wrong ? I thought SQLAlchemy if configured with a supported dialect, should work fine (I use it on MySQL quite well). Am I missing any configuration ? Any help appreciated.

RODBCext: SQL 42000 402 Error when using sqlExecute()

I'm working on a Shiny app for updating entries maintained in a SQLServer2008 remote DB. I've been connecting to the DB using RODBC and I'm attempting to use parameterized queries through RODBCext to support mass updates of information.
I'm able to get the parameterized queries to work from my Windows 7, RStudio running R 3.2.3, but for some reasons when I try to run the same code from the linux machine running the same version of R and connecting with the same version of the driver, I get the following error:
Error in sqlExecute(Connection, data = dat) :
42000 402 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]The data types char and text are incompatible in the equal to operator.
42000 8180 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Statement(s) could not be prepared.
[RODBCext] Error: SQLExecute failed
In addition: Warning messages:
1: In sqlExecute(Connection, data = dat) :
42000 402 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]The data types char and text are incompatible in the equal to operator.
2: In sqlExecute(Connection, data = dat) :
42000 8180 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Statement(s) could not be prepared.
Here is the simple example code that works properly on my windows machine, but not on the linux machine (I removed the connection string information):
library(RODBCext)
Connection <- odbcDriverConnect(paste('Driver=ODBC Driver 13 for SQL Server',
'Server=<Server IP>', 'Port=<Port>', 'Database=<Database>', 'UID = <UserID>',
'PWD=<Password>', sep = ';'))
dat <- data.frame(Node_ID = "999", NodeGUID = "AF213171-201B-489B-B648-F7D289B735B1")
query <- "UPDATE dbo.Nodes SET Node_ID = ? WHERE NodeGUID = ?"
sqlPrepare(Connection, query)
sqlExecute(Connection, data = dat)
In this example, the dataframe is created with the columns as factors. I've tried explicitly casting the columns as characters first, as this seemed to work for the users having trouble with dates, but that still results in the same SQL error. I've also tried casting the Node_ID as numeric to match the SQL table, and I get the same error. The columns in the Nodes table in SQL are defined as:
NodeGUID (PK, char(36), not null)
Node_ID (int, null)
I've tried combining the sqlPrepare and sqlExecute calls by supplying the query argument for sqlExecute, and from what I understand that's a trivial difference and it results in the same error.
I suspect there must be a difference in the drivers and how they implement whatever SQL calls sqlExecute() makes. I also suspect sqlExecute() must handle the data types, as my results don't change regardless of the column types.
Thank you for any help you can provide!
Thanks to everyone who took a look at my question.
One of the SQL Server folks at my job was able to solve the issue. They suggested explicitly casting the arguments in the SQL query written for sqlExecute(). Here's the code that works, note I know the GUID will always be 36 characters and I'm confident the rest of the arguments I use this query for will be less than 1000 when converted to strings:
my_query <- "UPDATE dbo.Nodes SET Node_ID = CAST(? As varchar(1000)) WHERE NodeGUID = CAST(? As varchar(36))"
sqlExecute(Connection, data = dat, query = my_query)
I'm guessing the driver for Windows is somehow handling the casting from text to varchar, but the linux driver does not.
I hope this helps others working with RODBCext. Thanks to Mateusz Zoltak and the team of contributors for a great package!

Resources