Without using dynamic SQL, and other than an If ELSE is there any way to test if a table has a full text index without causing additional locking.
I'm looking for some way that I can still execute:
SELECT * FROM Cars WHERE <not has full text index> OR (<has full text index> AND CONTAINS(*, 'fast'))
There is no full-text index on this the table Cars ideally I would like for it to just return all rows when we try and specify the contains string.
What I have currently from SQL is:
SELECT * FROM Cars
WHERE NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = object_id('Cars') AND COLUMNPROPERTY(object_id, name, 'IsFulltextIndexed') = 1)
OR (EXISTS (SELECT 1 FROM sys.columns WHERE object_id = object_id('Cars') AND COLUMNPROPERTY(object_id, name, 'IsFulltextIndexed') = 1)
AND CONTAINS(*, 'fast'))
Which parses fine but fails because:
Msg 7601, Level 16, State 1, Line 3 Cannot use a CONTAINS or FREETEXT
predicate on table or indexed view 'Cars' because it is not full-text
indexed.
Is there a way to do this without dynamic SQL and without using an IF ELSE?
Bonus points if you can explain why the optimizer doesn't short-circuit the 1=0 and CONTAINS from SELECT * FROM Cars WHERE 1=1 OR (1=0 AND CONTAINS(*, 'fast')).
In practice I will likely create a new class attribute and then use that to ignore the full text indexes in my ORM, but I am interested to see if there is another option.
No.
All single queries are compiled into a single plan, and so all the individual components must always be valid. It is not possible to write a single statement where different components are valid in different circumstances.
To do so require more traditional programatic constructs. These are available in T-SQL, but not within a single SQL statement. As such, the solutions you have listed as innapropriate are actually the ways to resolve such issues.
Related
I want to write a query that examines all the tables in an SQLite database for a piece of information in order to simplify my post-incident diagnostics (performance doesn't matter).
I was hoping to write a query that uses the sqlite_master table to get a list of tables and then query them, all in one query:
SELECT Name
FROM sqlite_master
WHERE Type = 'table' AND (
SELECT count(*)
FROM Name
WHERE conditions
) > 0;
However when attempting to execute this style of query, I receive an error no such table: Name. Is there an alternate syntax that allows this, or is it simply not supported?
SQLite is designed as an embedded database, i.e., to be used together with a 'real' programming language.
To be able to use such dynamic constructs, you must go outside of SQLite itself:
cursor.execute("SELECT name FROM sqlite_master")
rows = cursor.fetchall()
for row in rows:
sql = "SELECT ... FROM {} WHERE ...".format(row[0])
cursor.execute(sql)
I want to write a query that examines all the tables in an SQLite database for a piece of information in order to simplify my post-incident diagnostics (performance doesn't matter).
I was hoping to write a query that uses the sqlite_master table to get a list of tables and then query them, all in one query:
SELECT Name
FROM sqlite_master
WHERE Type = 'table' AND (
SELECT count(*)
FROM Name
WHERE conditions
) > 0;
However when attempting to execute this style of query, I receive an error no such table: Name. Is there an alternate syntax that allows this, or is it simply not supported?
SQLite is designed as an embedded database, i.e., to be used together with a 'real' programming language.
To be able to use such dynamic constructs, you must go outside of SQLite itself:
cursor.execute("SELECT name FROM sqlite_master")
rows = cursor.fetchall()
for row in rows:
sql = "SELECT ... FROM {} WHERE ...".format(row[0])
cursor.execute(sql)
I have a 11G database. I need to examine a number of stored procedures to see if they use a particular table. (Both front end and back end sps) I have full access to the database, and I also have a copy of all the individual sps for the project which are stored on a TFS.
I would like a way to generate a list of all the sps that interact with this particular table. I'm unfamiliar with how to go about searching for these. Can anyone advise the most logical way of obtaining this data?
Thanks.
If I understand this correctly, you're trying to search for occurrence of a table in all stored procs. In that case, you can use this query:
When searching for occurrences of SP in your schema
SELECT * FROM user_source WHERE text LIKE '%tab_name%';
When searching for occurrences of SP in all schemas
SELECT * FROM all_source WHERE text LIKE '%tab_name%';
Two things, in PL/SQL there are some changes which will require the recompilation of pl/sql object, other don't.
To see the first one, you have the ALL_DEPENDENCIES view. Or DBA_ if you prefer.
If you just want to see where the table name appears in all the pl/sql code, whether a change to the table will require recompilation or not, you can use ALL_SOURCE using a upper and %, but it might take some time.
I use PLSQL Developer, in which you can browse to a table (or other object), and view 'Referenced by', to see all objects that refer to the table. That's about as easy as it gets.
I can imagine other tools have similar features.
I don't know if this pre-parsed information is readily available in Oracle, but I can imagine so, since those tools seem to work pretty fast.
This information is available in the viewAll_DEPENDENCIES, which these tools probably use.
The source of stored procedures can be found in the USER_SOURCE (or ALL_SOURCE) view, in which the structure of the entire database is stored. Nevertheless, fetching and parsing the code from there would be quite cumbersome.
Here is snippet I wrote to perform impact analysis (ONLY MERGE, INSERT and UPDATE) for a given #schema (upper case only) and #table (upper case only). It will return all the procedure name, procedure code, from line number and to line number along with other details. It can be easily used to include functions objects as well instead of package. am working on a utility that can run across all schema or selected schema (that will include SELECT rows as well). Though this will be good enough for you to start working.
I know you can use the dependency and references available in Oracle to perform similarly. But for package level impact this is good addition. We can also use regex for more complex searches. But like operator is simple and efficient for my needs.
Note, this doesn't work on any dynamic code that may be working in your environment. This is just a appropriate starting point for quick one on impact with static PL/SQL code in your packages.
WITH TableDep as
-- This table returns references where the table is used within the code for UPDATE OR INSERT
(
SELECT
owner as schemaname,
name as packagename,
type as typename,
TEXT as refcodeline,
CASE WHEN upper(text) LIKE '%INSERT%' THEN 'INSERT'
WHEN upper(text) LIKE '%UPDATE%' THEN 'UPDATE'
WHEN upper(text) LIKE '%MERGE%' THEN 'MERGE'
END AS opr,
:Tablename AS Tablename,
line refline
FROM dba_source WHERE upper(owner) = upper(:OWNER)
AND type = 'PACKAGE BODY'
AND (
upper(text) LIKE ('%INSERT INTO '||:Tablename||'%')
OR
upper(text) LIKE ('%UPDATE%'||:Tablename||' %')
OR
upper(text) LIKE ('%MERGE%'||:Tablename||' %')
)
),
ProcedureDetails as
-- This code build all procedures within the package for references that is found in above query
(
SELECT
owner as schemaname,
name as packagename,
type as typename,
TEXT,
trim(REGEXP_SUBSTR(TEXT, '(PROCEDURE [[:print:]]+)\(',1,1,null,1)) as procedure_name,
line startline,
LEAD(line, 1) OVER (partition by name order by line)-1 as endline
FROM dba_source
WHERE owner = upper(:OWNER)
AND type = 'PACKAGE BODY'
AND upper(text) LIKE '%PROCEDURE%(%'
and exists (SELECt 1 FROM TableDep WHERE TableDep.packagename=name)
)
,ProcCode as
-- This code builds procedures into one cell per program for a given package. Later to find the effected procedures
(
SELECT
ProcTag.packagename ,
ProcTag.schemaname,
ProcTag.typename,
ProcTag.PROCEDURE_NAME,
ProcTag.startline,
ProcTag.endline,
TO_CLOB(rtrim(xmlagg(xmlelement(e,codeline.text).extract('//text()') order by line).GetClobVal(),',')) as Procedure_Code
FROM
ProcedureDetails ProcTag
INNER JOIN dba_source codeline ON ProcTag.packagename=codeline.name
AND ProcTag.schemaname=codeline.owner
and ProcTag.typename=codeline.type
and codeline.line between ProcTag.startline and ProcTag.endline
--WHERE PROCEDURE_NAME='PROCEDURE TRANS_KAT_INSO'
group by
ProcTag.packagename ,
ProcTag.schemaname,
ProcTag.typename,
ProcTag.PROCEDURE_NAME,
ProcTag.startline,
ProcTag.endline
)
-- extract all the reference code for the given table selected with it complete procedure code.
SELECT
ProcHeader.Packagename, ProcHeader.schemaname, ProcHeader.typename, ProcHeader.procedure_name, ProcHeader.Procedure_Code ,ProcHeader.startline,ProcHeader.endline,ProcReference.Tablename, ProcReference.opr
FROM
ProcCode ProcHeader
INNER JOIN
(
SELECT DISTINCT ProcCode.Packagename, ProcCode.schemaname, ProcCode.typename, ProcCode.procedure_name , TableDep.Tablename, TableDep.opr
FROM ProcCode
INNER JOIN TableDep ON ProcCode.packagename=TableDep.packagename
AND ProcCode.schemaname=TableDep.schemaname
and ProcCode.typename=TableDep.typename
and TableDep.refline between ProcCode.startline and ProcCode.endline
) ProcReference
ON ProcHeader.Packagename=ProcReference.Packagename
AND ProcHeader.schemaname=ProcReference.schemaname
AND ProcHeader.typename=ProcReference.typename
AND ProcHeader.procedure_name=ProcReference.procedure_name
;
This question already have an accepted answer but anyhow the query used inside the accepted answer will pick all the user sources which uses the particular table.
Because the question is specific about Procedures you can go for the below query to get the result
SELECT * FROM user_source WHERE text LIKE '%YourTableName%' and TYPE='PROCEDURE';
I want to search a text in a table without knowing its attributes.
Example : I have a table Customer,and i want to search a record which contains 'mohit' in any field without knowing its column name.
You are looking for Full Text Indexing
Example using the Contains
select ColumnName from TableName
Where Contains(Col1,'mohit') OR contains(col2,'mohit')
NOTE - You can convert the above Free text query into dynamic Query using the column names calculated from the sys.Columns Query
Also check below
FIX: Full-Text Search Queries with CONTAINS Clause Search Across Columns
Also you can check all Column Name From below query
Select Name From sys.Columns Where Object_Id =
(Select Object_Id from sys.Tables Where Name = 'TableName')
Double-WildCard LIKE statements will not speed up the query.
If you wanna make a full search on the table, you must surely be knowing the structure of the table. Considering the table has fields id, name, age, and address, then your SQL Query should be like:
SELECT * FROM `Customer`
WHERE `id` LIKE '%mohit%'
OR `name` LIKE '%mohit%'
OR `age` LIKE '%mohit%'
OR `address` LIKE '%mohit%';
Mohit, I'm glad you devised the solution by yourself.
Anyway, whenever you again face an unknown table or database, I think it will be very welcome the code snippet I just posted here.
Ah, one more thing: the answers given did not addressed your problem, did they?
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)