T-sql comparing results of linked server query with local query - sql

I am trying to compare the results of a linked server query with a local query. What I am try to do is find out what Logins exist on one server but not the other. Just windows auth accounts is fine for now.
My current query is
Select name
from [linkedServer].master.[sys].[server_principals]
Where name not in ('Select name from sys.server_principals')
What I get back is the result of the linked server query only with the where ignored. How do I go about comparing the results of the two?

First, use not exists. Second, I think your single quotes are wrong:
select sp.name
from [linkedServer].master.[sys].[server_principals] sp
where not exists (select 1
from sys.server_principals sp2
where sp2.name = sp.name
);
I strongly recommend that you get in the habit of using not exists with a subquery rather than not in, because not in returns no row if any value from the subquery is NULL. That is usually not desirable behavior.

Related

SQL injection payload after order by in SQL query

Trying to exploit SQL injection for my assignment. Is it possible to execute delete or drop query after order by in select query without using the semicolon in Postgresql?
This is my sample query:
Select *
from table
order by {sql injection payload}
Without using the semicolon in the payload, can we delete data or drop a table?
https://stackoverflow.com/a/6800585
Do we have similar to this Postgrsql?
I tried
Select * from (delete from table_name returning *) a
But getting sql error as 'syntax error at or near from'
Check this document it says we can bypass forbidden character by CHR()
https://book.hacktricks.xyz/pentesting-web/sql-injection/postgresql-injection
DELETE cannot be put inside a subquery. Nor can DELETE be part of a UNION.
So aside from running a second query (that is, separated by a semicolon), there's almost no way you can do what you describe.
You could invoke a stored procedure or function, if you knew of an existing function that performs a DELETE. Example:
Select *
from table
order by {sql injection payload}
After your payload modifies this query:
Select *
from table
order by SomeFunctionThatDeletes()
Another type which works because you can select from a procedure in PostgreSQL:
Select *
from table
order by id
UNION
Select *
from SomeProcedureThatDeletes()
You can't create the function or procedure with SQL injection, so that routine must exist already, and you would need to know its name and how to call it.
DELETE or DROP TABLE are not the only bad things that can happen from SQL injection. It could be a problem if the query returns data that the current user shouldn't have privilege to see. For example, records about a different user's purchases or medical history.
SQL injection can also be accidental instead of malicious. I would even say that most instances of SQL injection result in simple errors instead of data breaches. Those aren't really attacks, but they lead to an unsatisfactory experience for your users.

How to Separate server name and instance name from ##servername in SQL Server

How can I separate Server name and Named instance from ##servername. I know I could just use serverproperty to collect just the Machine name or instance name but I am working with two tables where I have to join on the table name. Table1 has the just the Server name as an "TESTDB01" and Table2 has Server Name and the Instance name as an TESTDB01\InstanceName.
When I Join these tables together, anything with the Named Instances will be missed as it has "\InstanceName" , only the default Instance will get picked up.
You could use this:
LEFT(##SERVERNAME,CHARINDEX('\',##SERVERNAME)-1)
But you would be better off separating them in your table in order to make your queries sargable. Join conditions using these string functions often (usually) result in poor query performance. LEFT() and RIGHT() could use indexes but frequently doesn't; SUBSTRING() can't.
Simply use replace in your join condition
on substring(tbl2.instancename, 1, CharIndex('\', tbl2.instancename) - 1)
= tbl1.servername

Update from aggregate in same table if aggregate value wrong - SQL Server/Oracle/Firebird

I have a table with grouped tasks:
tt_plan_task_id is the id
records with tt_plantype=1 represent 'groups'
tasks in/under a group have a tt_group_id pointing to the tt_plan_task_id
there are tasks that don't belong to a group (tt_group_id is null)
groups nest multiple levels
I need to fix (update) the tt_fromdate field values for the group records if they do not match the min(tt_fromdate) from the underlying tasks (they always have a value).
To fix them all I could do
update tt_plan_task g
set tt_fromdate=
(select min(t.tt_fromdate) from tt_plan_task t
where (t.tt_group_id=g.tt_plan_task_id))
where (g.tt_plantype=1)
This statement avoids the UPDATE FROM syntax that I see in many (SQL server) answers - Firebird does not support that.
There are 2 complications
I want to do the update only if g.tt_fromdate <> min(t.tt_fromdate), so I would have to add a reference to min(tt_fromdate) to the outer where.
I tried using an alias for the aggregate and referencing that but that got me nowhere (syntax errors)
SQL Server does not like the table alias in the update, but solutions like these use the UPDATE FROM syntax again ;-( How do I work around that then?
How do I tie 1. and 2. into my update statement so that it works?
As noted in the title, this needs to execute in SQL Server, Oracle, and Firebird
Note: Since groups can contain groups, the update should ideally be executed 'from the bottom up', i.e. deepest groups first.
But since this is just a rough correction for a corrupt database, doing one 'lineair' pass over all groups is good enough.
To get around SQL Server's non-standard way for update table aliases, simply don't use any.
As to using the aggregate result in both the SET clause and the WHERE clause, I suppose the only way all DBMS work with, is to write the aggregation query twice.
update tt_plan_task
set tt_fromdate =
(
select min(t.tt_fromdate)
from tt_plan_task t
where t.tt_group_id = tt_plan_task.tt_plan_task_id
)
where (tt_plantype=1)
and
(
tt_fromdate <>
(
select min(t.tt_fromdate)
from tt_plan_task t
where t.tt_group_id = tt_plan_task.tt_plan_task_id
)
);

SQL Joins Not Returning All Field Values; Different Field Values Returned When Order Changed

I'm using the following SQL to query 3 simple tables and pull back results. When I run this query in SQL Server 2005 EM (database that's being used), the correct recordset results are returned. When I execute this from my webpage (ASP) via an SQL statement or a stored procedure, I get blank values for some of the columns. Also, I noticed that when I change the order of the tables being selected in my FROM clause, some of the previous columns then return blank values. Is there something wrong with my SQL for it not to work when calling it? I developed my app locally and it works fine. When I deployed it to the client's network, the problems started... The client is running Win 2000 SP4 as their application server and my app is developed in ASP 3.0 with a SQL Server 2005 datastore.
SELECT
Scorecard_Measure.Measure,
Scorecard_Measure.Target,
Scorecard_Measure.YTD,
Scorecard_Measure.Status,
Scorecard_Measure.Explanation,
Scorecard_Measure.Division,
Scorecard_Measure.ZIndex,
Scorecard_Measure.LastUpdated,
Scorecard_Measure.ID,
Scorecard_Objectives.Details,
Scorecard_Objectives.ZIndex,
Scorecard_ObjectiveCats.IdentityLetter
FROM
[Scorecard_Measure],
[Scorecard_Objectives],
[Scorecard_ObjectiveCats]
WHERE
Scorecard_Measure.ObjID=Scorecard_Objectives.ID
AND Scorecard_Objectives.ObjCatID = Scorecard_ObjectiveCats.ID
AND Scorecard_Measure.FiscalYear = '2011'
AND Scorecard_Measure.Publish='Y'
ORDER BY Scorecard_Measure.LastUpdated DESC
Scorecard_Objectives.ID is a foreign key in the Scorecard_Measure table, Scorecard_ObjectiveCats.ID is a foreign key in the Scorecard_Objectives table.
Also, a weird occurence. I have two column names that are the same and when I reference those columns, the server isn't throwing an error like I've seen before saying "your results have columns with the same name, reference them using the tables they come from"... e.g. rs("Scorecard_Objectives.ZIndex") and rs("Scorecard_Measure.ZIndex") -- when I use these references, I get an error from IIS.
Any points is appreciated. Thanks in advance!
Access Both ZINDEX with different variables. Try this join query.
SELECT
Scorecard_Measure.Measure,
Scorecard_Measure.Target,
Scorecard_Measure.YTD,
Scorecard_Measure.Status,
Scorecard_Measure.Explanation,
Scorecard_Measure.Division,
Scorecard_Measure.ZIndex as MZIndex,
Scorecard_Measure.LastUpdated,
Scorecard_Measure.ID,
Scorecard_Objectives.Details,
Scorecard_Objectives.ZIndex as OZIndex,
Scorecard_ObjectiveCats.IdentityLetter
FROM
Scorecard_Measure INNER JOIN Scorecard_Objectives
ON Scorecard_Measure.ObjID=Scorecard_Objectives.ID
AND Scorecard_Measure.FiscalYear = '2011'
AND Scorecard_Measure.Publish='Y'
INNER JOIN Scorecard_ObjectiveCats
ON Scorecard_Objectives.ObjCatID = Scorecard_ObjectiveCats.ID
ORDER BY Scorecard_Measure.LastUpdated DESC

Operation must use an updatable query. (Error 3073)

I have written this query:
UPDATE tbl_stock1 SET
tbl_stock1.weight1 = (
select (b.weight1 - c.weight_in_gram) as temp
from
tbl_stock1 as b,
tbl_sales_item as c
where
b.item_submodel_id = c.item_submodel_id
and b.item_submodel_id = tbl_stock1.item_submodel_id
and b.status <> 'D'
and c.status <> 'D'
),
tbl_stock1.qty1 = (
select (b.qty1 - c.qty) as temp1
from
tbl_stock1 as b,
tbl_sales_item as c
where
b.item_submodel_id = c.item_submodel_id
and b.item_submodel_id = tbl_stock1.item_submodel_id
and b.status <> 'D'
and c.status <> 'D'
)
WHERE
tbl_stock1.item_submodel_id = 'ISUBM/1'
and tbl_stock1.status <> 'D';
I got this error message:
Operation must use an updatable query. (Error 3073) Microsoft Access
But if I run the same query in SQL Server it will be executed.
Thanks,
dinesh
I'm quite sure the JET DB Engine treats any query with a subquery as non-updateable. This is most likely the reason for the error and, thus, you'll need to rework the logic and avoid the subqueries.
As a test, you might also try to remove the calculation (the subtraction) being performed in each of the two subqueries. This calculation may not be playing nicely with the update as well.
Consider this very simple UPDATE statement using Northwind:
UPDATE Categories
SET Description = (
SELECT DISTINCT 'Anything'
FROM Employees
);
It fails with the error 'Operation must use an updateable query'.
The Access database engine simple does not support the SQL-92 syntax using a scalar subquery in the SET clause.
The Access database engine has its own proprietary UPDATE..JOIN..SET syntax but is unsafe because, unlike a scalar subquery, it doesn’t require values to be unambiguous. If values are ambiguous then the engine silent 'picks' one arbitrarily and it is hard (if not impossible) to predict which one will be applied even if you were aware of the problem.
For example, consider the existing Categories table in Northwind and the following daft (non-)table as a target for an update (daft but simple to demonstrate the problem clearly):
CREATE TABLE BadCategories
(
CategoryID INTEGER NOT NULL,
CategoryName NVARCHAR(15) NOT NULL
)
;
INSERT INTO BadCategories (CategoryID, CategoryName)
VALUES (1, 'This one...?')
;
INSERT INTO BadCategories (CategoryID, CategoryName)
VALUES (1, '...or this one?')
;
Now for the UPDATE:
UPDATE Categories
INNER JOIN (
SELECT T1.CategoryID, T1.CategoryName
FROM Categories AS T1
UNION ALL
SELECT 9 - T2.CategoryID, T2.CategoryName
FROM Categories AS T2
) AS DT1
ON DT1.CategoryID = Categories.CategoryID
SET Categories.CategoryName = DT1.CategoryName;
When I run this I'm told that two rows have been updated, funny because there's only one matching row in the Categories table. The result is that the Categories table with CategoryID now has the '...or this one?' value. I suspect it has been a race to see which value gets written to the table last.
The SQL-92 scalar subquery is verbose when there are multiple clauses in the SET and/or the WHERE clause matches the SET's clauses but at least it eliminates ambiguity (plus a decent optimizer should be able to detects that the subqueries are close matches). The SQL-99 Standard introduced MERGE which can be used to eliminate the aforementioned repetition but needless to say Access doesn't support that either.
The Access database engine's lack of support for the SQL-92 scalar subquery syntax is for me its worst 'design feature' (read 'bug').
Also note the Access database engine's proprietary UPDATE..JOIN..SET syntax cannot anyhow be used with set functions ('totals queries' in Access-speak). See Update Query Based on Totals Query Fails.
Keep in mind that if you copy over a query that originally had queries or summary queries as part of the query, even though you delete those queries and only have linked tables, the query will (mistakenly) act like it still has non-updateable fields and will give you this error. You just simply re-create the query as you want it but it is an insidious little glitch.
You are updating weight1 and qty1 with values that are in turn derived from weight1 and qty1 (respectively). That's why MS-Access is choking on the update. It's probably also doing some optimisation in the background.
The way I would get around this is to dump the calculations into a temporary table, and then update the first table from the temporary table.
There is no error in the code. But the error is Thrown because of the following reason.
Please check weather you have given Read-write permission to MS-Access database file.
The Database file where it is stored (say in Folder1) is read-only..?
suppose you are stored the database (MS-Access file) in read only folder, while running your application the connection is not force-fully opened. Hence change the file permission / its containing folder permission like in C:\Program files all most all c drive files been set read-only so changing this permission solves this Problem.
In the query properties, try changing the Recordset Type to Dynaset (Inconsistent Updates)