Strange security bug SQL Server 2008 and Delphi 10 Seattle - sql-server-2008

I met strange security result on my Delphi 10 Seattle using SQL Server 2008.
I need read-only DB access, so made dedicated r/o user; ADO connection string in TADOConnection uses its credentials. Test query
select system_user
shows its username.
T-SQL code looks like:
select SValue
from Table
where SValue = '1';
update Table
set SValue = '1';
In SQL Server Management Studio this code shows error if I login with r/o user. When I use this code in Delphi with TADOQuery.ExecSQL, it also shows exception with r/o access error. But when I use it as TADOQuery.Open it works fine and successfully updates the database.
What it could be a cause of such behavior and how I could prevent further write access on Open?

Related

SSIS Data flow task and "mixed" select

Can't get following to work. Notice it worked just fine using SQL Server 2000 DTS package.
AXDB is external server (SQL Server 2000 Enterprise) and OLAP being the local database, SQL Server 2008 R2 standard (olap is used select statement getting the date to pass on the external SQL Server). Adding server name doesn't help.
Servers are linked if it matters, probably not.
If I just write the date there instead of trying to get it via select statement it works fine as expected.
How to achieve what I want here, notice I have about 100 such packages.
Pics are here:
Error:
Remove the ' ticks from around the sub-select:
...AND DATEPHYSICAL <= (SELECT lkpv FROM OLAP.dbo.laadimisaeg)
Right now your select is being read as a string, and that string is trying to be compared to a date.

Special statements with Openquery

I would like to transfer data from a MS SQL Server database to a MySQL database. So, I added a linked server to MS SQL so that I can use Openquery to insert the data in the MySQL database. I want to optimize the performance of the data transfer and I found the guidelines for improving performance of data loading in MySQL.
One optimization consists of disabling AUTOCOMMIT mode, however I was not able to do it using Openquery.
I tried both ways:
SELECT * from openquery(MYSQL,'SET autocommit=0')
exec openquery(MYSQL,'SET autocommit=0')
and I got:
Cannot process the object "SET autocommit=0". The OLE DB provider
"MSDASQL" for linked server "MYSQL" indicates that either the object
has no columns or the current user does not have permissions on that
object.
Is it possible to execute such statements through openquery?
Thanks,
Mickael
OPENDATASOURCE() and OPENROWSET() allow for add-hoc server connections. You do not need to define a linked server ahead of time.
The OPENQUERY() depends upon a static linked server being defined ahead of time.
Here is the MSDN reference.
http://technet.microsoft.com/en-us/library/ms188427.aspx
Most of the examples show a DML (SELECT, UPDATE, DELETE, INSERT) using the OPENQUERY() as the source or destination of the command. What you are trying to do is execute a session command. Therefore it will fail. Also, you might not even know if the session stays open for the next call.
Why not package up the logic on the MYSQL server as a stored procedure. The stored procedure can be executed on a linked server by using a four-part name?
For example:
INSERT INTO #results
EXEC server.database..stored-proc
This assumes MYSQL has the same object structure as ORACLE. Since I am not a MYSQL person, I can not comment. I allow you to research this little item.
But this should work. It will allow you to package any type of logic in the MYSQL database.
If you want to use SSIS to transfer data from SQL Server to MYSQL.
For the ADO.NET Destination to work properly, the MySQL database needs to have the ANSI_QUOTES SQL_MODE option enabled. This option can be enabled globally, or for a particular session. To enable it for a single session:
1 - Create an ADO.NET Connection Manager which uses the ODBC driver
2 - Set the connection manager’s RetainSameConnection property to True
3 - Add an Execute SQL Task before your data flow to set the SQL_MODE – Ex. set sql_mode='STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,ANSI_QUOTES'
4 - Make sure that your Execute SQL Task and your ADO.NET Destination are using the same connection manager.
Matt Mason did this on a reply.. The key is item #2, use the same connection.
http://blogs.msdn.com/b/mattm/archive/2009/01/07/writing-to-a-mysql-database-from-ssis.aspx#comments
Also, CozyRoc has a custom ODBC driver that might be faster / more reliable than the free one from MYSQL.
http://cozyroc.com/ssis/odbc-destination

Error when trying to update via linked server (mssql -> mysql) - Select works

I am having an issue when trying to do an update via a linked server. Error is the following:
OLE DB provider "MSDASQL" for linked server "**LINKED_SERVER_NAME" returned message "Data provider or other service returned an E_FAIL status.".
Msg 7330, Level 16, State 2, Line 1
Cannot fetch a row from OLE DB provider "MSDASQL" for linked server "LINKED_SERVER_NAME".
I have no problem selecting data but any time I try to do an update it fails. My update code:
Update [LINKED_SERVER_NAME]...[Table_Name]
SET post_content = 'alert'
where ID = 5061
This is my select statement which DOES work:
select top 100 * from [LINKED_SERVER_NAME]...[Table_Name] where ID = 5061
I am using:
Microsoft SQL Server Management Studio 2008
Trying to connect from MS SQL -> MySQL via ODBC Connector 5.2 (5.1
has same issue)
UPDATE
I have tried to use "OPENQUERY" -> this does not work either
OPENQUERY is not new but it is far more reliable when dealing with non-microsoft linked servers.
UPDATE OPENQUERY (LINKED_SERVER_NAME, 'SELECT post_content FROM Table_Name WHERE ID = 5061')
SET post_content = 'alert';
Do not use [ ] square brackets in mysql queries; you can use apostrophe instead.
Check that you have update permissions on the table.
Try running the update directly on a mysql connection. This may be an error not related to linked servers.
Is the mysql table a view? It may not be configured correctly as an updatable view.
MySQL CREATE VIEW Syntax
If this still doesn't solve it, paste your actual openquery code into the question.

SQL Server 2008 - Update system catalog from stored procedure

We had some old stored procedures in SQL Server 2000 which updated system catalog from an application which was used for user application security which is tied to SQL Server roles to take advantage of SQL Server in-built security and NT logins.
When we migrate DB to SQL Server 2008 and try to run these stored procedure we get SQL Server 2008 error
Ad hoc updates to system catalogs are not allowed.
I searched around and found that from SQL Server 2005 onwards MS do not support catalog updates (unless using Dedicated Administrator Connection (DAC) ).
If anyone can help me with how to do this in new versions or any other alternative (like .Net code run in Sql server??) that will be great.
Some sample queries below
update sysusers
set roles = convert(varbinary(2048), substring(convert(binary(2048), roles), 1, #ruidbyte-1)
+ convert(binary(1), (~#ruidbit) & substring(convert(binary(2048), roles), #ruidbyte, 1))
+ substring(convert(binary(2048), roles), #ruidbyte+1, 2048-#ruidbyte)),
updatedate = getdate()
where uid = #memuid
delete from syspermissions where grantee = #uid
delete from sysusers where uid = #uid
insert into sysusers
values(#uid, 0, #rolename, NULL, 0x00, getdate(), getdate(), #owner, NULL)
There is no routine reason to update system tables in SQL Server. Ever.
There is a whole array of commands and system stored procedures to do it properly in all versions of SQL Server.
You can't anyway as you noted: there is no hack or workaround
Updating a system table can be a dangerous task, as it may lead to unexpected results. So before you do that just make sure that you are very confident with whatever you are doing. It would be advisable that you do the changes on a replica of the original database to prevent unwanted results or crashes in the database.
The possible ways could be:
Use a DAC. You can get the technique after searching it on google. It is more of hacking the system tables.
Use the following code:
sp_configure 'allow updates',1
go
//your code
reconfigure with override
go
reconfigure would configure back your database.
setting 'allow updates' to '1' would allow you to update the system tables.
But the best way would be to find an another alternative for your task.!

varchar(max) datatype odbc mapping to ms-access2003

i have tested the difference between defining varchar(max) in opposite text with our legacy application on a SQL Server 2005. All went very well and the new datatype reduced in a particular test case the amount of reads from 78 to 8 that represents a performance gain which we dont want to miss.
But now on the target sqlserver of version 2008 i get a problem: the columns of datatype varchar(max) are now mapped to the msaccess2003 datatype text(255).
Where is this odbc mapping defined? Which parameter must be changed to get the desired mapping varchar(max) to memo?
Peace
Ice
Update:
Now i know that when i connect the Access ODBC-Sources while remotely logged on the Win 2008 / SQL Server 2008 the mapping of varchar(max) to ms-access-datatype memo is correct.
We work in a LAN and while logged on the Win2003-Citrix-Server connecting the ODBC-Sources with ms-access the mapping goes wrong.
Very weird situation, whats is going on?
Switching from Native SQL Server Native Client 10.0 to baked-in WinXP SQL Server driver for ODBC connection worked for me.
SQL Server 2008 varchar(max) now mapped to Access 2003 memo in my linked table.
While this article refers to importing, it may be of interest to you: http://www.windows-tech.info/15/313c8cc3ac03f313.php
It states:
Your field in SQL Server should be an
NVARCHAR(MAX) to map directly to the
MEMO field in Access. The data types
inside the SSIS package for that field
should be DT_NTEXT.
-- Phil Brammer