Modify format of sqllite select columns - sqlite

I am pretty new to SqlLite db. I have the following table along with its data. I want to modify the columns data which appears as output.
CREATE TABLE students (studentId TEXT, firstName TEXT, studentNo TEXT);
INSERT INTO students VALUES ("6b975012-ec43-496e-b1df-44a214437287" ,"Virat" ,"530642685”);
The following select query should return
SELECT studentNo from students;
XXXXX2685
I have tried using built in functions available with SqlLite without any luck.
SELECT REPLACE(studentNo, '', 'X') as Student_SSN from students;
Could anyone please let me know how to achieve this.
thanks

select studentNo,
format('%.*c', length(studentNo)-4, 'X') || substr(studentNo,-4,4) as student_SSN
from students;
Result:
studentNo|student_SSN|
---------+-----------+
530642685|XXXXX2685 |
If the number of 'X' is not important, use a string literal:
select studentNo,
'XXXXX' || substr(studentNo,-4,4) as student_SSN
from students;

Related

ORA-01427: single-row subquery returns more than one row when inserting multiple rows

I am trying to assign or give all permissions of a user to another given user, 13053 but facing this Oracle error, ORA-01427: single-row subquery returns more than one row and i know exactly which part of my SQL statement shown below is returning this error but failed to handle it because what i want to achieve is to give those multiple rows returned to the given user with an id of 13053.
My attempt
INSERT INTO userpermissions (
userid,permissionid
) VALUES (
13053,( SELECT permissionid
FROM userpermissions
WHERE userid = ( SELECT userid
FROM users
WHERE username = '200376'
)
)
);
Any help ?
Thanks in advance.
A rewrite ought to do the trick:
INSERT INTO USERPERMISSIONS(
USERID,
PERMISSIONID
)
SELECT 13053 AS USERID,
p.PERMISSIONID
FROM USERPERMISSIONS p
WHERE p.userid = (SELECT userid FROM users WHERE username = '200376');
The problem with the original insert is that you are using single-row insert syntax when you are really trying to insert a set of rows.
Including the target userid as a literal is one way to make the set of rows look the way I am assuming you intend.

Android SQLITE Insert into table with values coming from a subquery

In my db-driven app I need to perform insert into queries in which the value for one or more field comes from a subquery.
The insert into statement may look like the following example:
INSERT INTO MyTable (field_1, field_2)
VALUES('value for field 1', (SELECT field_x FROM AnotherTable WHERE ...))
At present I am doing it manually building the query:
String MyQuery = "INSERT INTO mytable (field_1, field_2)
VALUES('value for field 1', (SELECT field_x FROM AnotherTable WHERE ...))"; // Of course my query is far more complex and is built in several steps but the concept is safe, I end up with a SQL String
SQLiteDatabase= db = getWritableDatabase();
db.execSQL(MyQuery); // And it works flawlessy as it was a Swiss Clock
What i would like to do instead is:
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("field_1", "value for field 1");
values.put("field_2", ThisIsAQuery("(SELECT field_x FROM AnotherTable WHERE ...)"));
db.insert("MyTable", null, values);
db.close();
Where the fake method ThisIsAQuery(...) is the missing part, something that should tell the query builder that "SELECT.." is not a value but a query that should be embedded in the insert statement.
Is there a way to achieve this?
The whole point of the ContentValues container is to be able to safely use strings without interpreting them as SQL commands.
It is not possible to use subqueries with insert(). The only way to get a value from another table is by executing a separate query; in this case, ThisIsAQuery() would be stringForQuery() or longForQuery().

SQLite Schema Information Metadata

I need to get column names and their tables in a SQLite database. What I need is a resultset with 2 columns: table_name | column_name.
In MySQL, I'm able to get this information with a SQL query on database INFORMATION_SCHEMA. However the SQLite offers table sqlite_master:
sqlite> create table students (id INTEGER, name TEXT);
sqlite> select * from sqlite_master;
table|students|students|2|CREATE TABLE students (id INTEGER, name TEXT)
which results a DDL construction query (CREATE TABLE) which is not helpful for me and I need to parse this to get relevant information.
I need to get list of tables and join them with columns or just get columns along with table name column. So PRAGMA table_info(TABLENAME) is not working for me since I don't have table name. I want to get all column metadata in the database.
Is there a better way to get that information as a result set by querying database?
You've basically named the solution in your question.
To get a list of tables (and views), query sqlite_master as in
SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;
(see the SQLite FAQ)
To get information about the columns in a specific table, use PRAGMA table_info(table-name); as explained in the SQLite PRAGMA documentation.
I don't know of any way to get tablename|columnname returned as the result of a single query. I don't believe SQLite supports this. Your best bet is probably to use the two methods together to return the information you're looking for - first get the list of tables using sqlite_master, then loop through them to get their columns using PRAGMA table_info().
Recent versions of SQLite allow you to select against PRAGMA results now, which makes this easy:
SELECT
m.name as table_name,
p.name as column_name
FROM
sqlite_master AS m
JOIN
pragma_table_info(m.name) AS p
ORDER BY
m.name,
p.cid
where p.cid holds the column order of the CREATE TABLE statement, zero-indexed.
David Garoutte answered this here, but this SQL should execute faster, and columns are ordered by the schema, not alphabetically.
Note that table_info also contains
type (the datatype, like integer or text),
notnull (1 if the column has a NOT NULL constraint)
dflt_value (NULL if no default value)
pk (1 if the column is the table's primary key, else 0)
RTFM: https://www.sqlite.org/pragma.html#pragma_table_info
There are ".tables" and ".schema [table_name]" commands which give kind of a separated version to the result you get from "select * from sqlite_master;"
There is also "pragma table_info([table_name]);" command to get a better result for parsing instead of a construction query:
sqlite> .tables
students
sqlite> .schema students
create table students(id INTEGER, name TEXT);
sqlite> pragma table_info(students);
0|id|INTEGER|0||0
1|name|TEXT|0||0
Hope, it helps to some extent...
Another useful trick is to first get all the table names from sqlite_master.
Then for each one, fire off a query "select * from t where 1 = 0". If you analyze the structure of the resulting query - depends on what language/api you're calling it from - you get a rich structure describing the columns.
In python
c = ...db.cursor()
c.execute("select * from t where 1=0");
c.fetchall();
print c.description;
Juraj
PS. I'm in the habit of using 'where 1=0' because the record limiting syntax seems to vary from db to db. Furthermore, a good database will optimize out this always-false clause.
The same effect, in SQLite, is achieved with 'limit 0'.
FYI, if you're using .Net you can use the DbConnection.GetSchema method to retrieve information that usually is in INFORMATION_SCHEMA. If you have an abstraction layer you can have the same code for all types of databases (NOTE that MySQL seems to swich the 1st 2 arguments of the restrictions array).
Try this sqlite table schema parser, I implemented the sqlite table parser for parsing the table definitions in PHP.
It returns the full definitions (unique, primary key, type, precision, not null, references, table constraints... etc)
https://github.com/maghead/sqlite-parser
The syntax follows sqlite create table statement syntax: http://www.sqlite.org/lang_createtable.html
This is an old question but because of the number of times it has been viewed we are adding to the question for the simple reason most of the answers tell you how to find the TABLE names in the SQLite Database
WHAT DO YOU DO WHEN THE TABLE NAME IS NOT IN THE DATABASE ?
This is happening to our app because we are creating TABLES programmatically
So the code below will deal with the issue when the TABLE is NOT in or created by the Database Enjoy
public void toPageTwo(View view){
if(etQuizTable.getText().toString().equals("")){
Toast.makeText(getApplicationContext(), "Enter Table Name\n\n"
+" OR"+"\n\nMake Table First", Toast.LENGTH_LONG
).show();
etQuizTable.requestFocus();
return;
}
NEW_TABLE = etQuizTable.getText().toString().trim();
db = dbHelper.getWritableDatabase();
ArrayList<String> arrTblNames = new ArrayList<>();
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE
type='table'", null);
if (c.moveToFirst()) {
while ( !c.isAfterLast() ) {
arrTblNames.add( c.getString( c.getColumnIndex("name")) );
c.moveToNext();
}
}
c.close();
db.close();
boolean matchFound = false;
for(int i=0;i<arrTblNames.size();i++) {
if(arrTblNames.get(i).equals(NEW_TABLE)) {
Intent intent = new Intent(ManageTables.this, TableCreate.class
);
startActivity( intent );
matchFound = true;
}
}
if (!matchFound) {
Toast.makeText(getApplicationContext(), "No Such Table\n\n"
+" OR"+"\n\nMake Table First", Toast.LENGTH_LONG
).show();
etQuizTable.requestFocus();
}
}

How to find name of the stored procedure using Column name in Oracle 11g

I have hundreds of stored procedures and i want to find out the name of the procedure which uses the particular column name in query
This will do it, but might produce false positives for generic column names
SELECT DISTINCT type, name
FROM dba_source
WHERE owner = 'OWNER'
AND text LIKE '%COLUMN_NAME%';
where OWNER is the schema which owns the stored procedures you want to search and COLUMN_NAME is the column name that you want to find. If you don't use mixed case column names then you can replace the last line with
AND UPPER(text) LIKE '%COLUMN_NAME%';
and enter the column name in capitals to get a case insensitive search.
There is no guaranteed way, but you can search user/all/dba_source using regexp_like to check for whole words, and cross-reference that with user/all/dba_dependencies to narrow down the list of packages to check.
select s.name, s.type, s.line, s.text
from user_source s
where ltrim(s.text,chr(9)||' ') not like '--%'
and regexp_like(lower(s.text),'\Wyour_column_name_here\W')
and (s.name, s.type) in
( select d.name, d.type
from user_dependencies d
where d.referenced_owner = user
and d.referenced_name = 'YOUR_TABLE_NAME_HERE' );
or if there could be references to it from other schemas,
select s.owner, s.name, s.type, s.line, s.text
from all_source s
where ltrim(s.text,chr(9)||' ') not like '--%'
and regexp_like(lower(s.text),'\Wyour_column_name_here\W')
and (s.owner, s.name, s.type) in
( select d.owner, d.name, d.type
from all_dependencies d
where d.referenced_owner = user
and d.referenced_name = 'YOUR_TABLE_NAME_HERE' );
You might make it just use select distinct s.owner, s.name, s.type ... to get a list of objects to investigate.

Efficient SQL procedure to get data from name value pair table into DataSet?

Using SQL Server, have a name value pair table. Each row is basically userid, contentid, sectionid, parameter, value. So there is data I want to display in a table such as user information. Each bit of information is in it's own row, sow how do I get it into a DataSet for use in a Repeater? Can I somehow merge the rows into one? So I can get multiple parameter/value pairs on one row?
so like...
two rows for user 32:
(param / value)
fname / Bob
lname / Smith
displayed on one row in a repeater like this:
Bob Smith
Any ideas? Oh yeah and the reason it is in the name/value pair format is to adhere to a required standard.
Maybe something like...
SELECT fff.firstname, lll.lastname
FROM (
SELECT ff.value AS firstname
FROM PairTable AS ff
WHERE ff.param = 'fname'
AND ff.userId = 32
) fff, (
SELECT ll.value AS lastname
FROM PairTable AS ll
WHERE ll.param = 'lname'
AND ll.userId = 32
) lll
Sucky standard.... :)
Anyway, your best bet is to play some magic (cursor) with your stored proc and return the data from the stored procedure in the format you want. Then binding to a DataSet, or a string list, is trivial.
Another alternative is PIVOT.
Something like this (untested because I have no SQL Server around now)
SELECT UserID, [fname] AS firstname, [lname] AS lastname
FROM
(SELECT UserID, value, name from PairTable WHERE UserID=32 ) p
PIVOT
(
value
FOR name IN
( [fname], [lname] )
) AS pvt
That table is awful. No offense ;-)
Relational databases just doen't do EAV tables very well.
You can also group, and do conditional CASE statements - like this:
SELECT UserID,
MAX(CASE WHEN param = 'fname' THEN value ELSE '' END) AS fname,
MAX(CASE WHEN param = 'lname' THEN value ELSE '' END) AS lname
FROM MyEAVTable
GROUP BY UserID
The PIVOT syntax is great - the only benefit to this solution is that it will work with SQL 2000 as well.

Resources