query for null values in web2py DAL - data-access-layer

Using the web2py DAL, how do a create a query to select for records will NULL values in a particular field?

Use this pattern: db(db.table.field==None).select()

Related

Insert into a BigQuery table with a template suffix using the web-ui

Using the Big Query Streaming API its possible to partition tables with a template suffix:
<targeted_table_name> + <templateSuffix>
eg. targettable_suffix
How can this be done from the web ui in an insert statement?
For example:
insert into `project123.dataset123.targettable_suffix`
(`id`, `value`) values ('123', 'abc')
(Where a table exists called targettable but the suffix table has not been created.)
The INSERT statement requires that the target table has been created in advance. Use a CREATE TABLE statement first to create it, then use INSERT. Note that the BigQuery team strongly recommends using partitioned tables instead of multiple tables that share a prefix, however, and if you use a partitioned table, you only need to create it once.

Postgres Insert without ANY VALUES FOR COLUMNS. ALL ARE DEFAULT

I have a table in Postgres that only has default column values (id, created_at).
The only way I can insert into this table is
INSERT INTO pages(id) VALUES(DEFAULT) RETURNING id;
Why can't I do this:
INSERT INTO pages RETURNING id;
Just curious.
You can use either :
INSERT INTO test DEFAULT VALUES returning id;
And all the explanations you want are right here : https://www.postgresql.org/docs/current/sql-insert.html
The syntax of PostgreSQL is quite imposed.
DEFAULT VALUES :
All columns will be filled with their default values. (An OVERRIDING clause is not permitted in this form.)
you need the values keyword, otherwise how would you tell how many rows you want to insert? However, you do not require the field names, so you can shorten your query a (very) little bit:
INSERT INTO pages VALUES(DEFAULT) RETURNING id;

SQL foreach loop

I'm very new at SQL scripts and couldn't figure out how to make a specific for each loop. I need to do something like this:
I have Sites and SiteCrawls tables.
Basically, for every site I need to create a new SiteCrawl and that SiteCrawl's Site_ID column will equal to that site's ID.
How can I do this?
insert SiteCrawl
(
Site_ID
)
select
s.Site_ID
from Site as s
where s.Site_ID not in (select Site_ID from SiteCrawl)
insert into site_crawl (site_id) values (select site_id from site);
So basically: there is no specific for/each in plain SQL, you handle tables and rows of results always as one statement.
So you could also say: there is no way an SQL Statement is something else than a for/each.
With that knowledge, you can see that the above query will insert one row into site_crawl for every site_id in the site table. You most likely want to use more values than this, but given the information from your question that is all I can do for you :)
Also: you want to read more about what sql is and how its used.
Have fun, SQL is a lot of fun!
In SQL you typically don't want to loop over every record. It's very inefficient.
You could do something like
insert into SiteCrawl (Site_Id)
select Id from Sites
insert into SiteCrawls (SiteID)
select SiteID
from Sites
you can do it by trigger
CREATE TRIGGER tg AFTER INSERT ON `Sites`
FOR EACH ROW
BEGIN
insert into SiteCrawls(Site_ID) values (NEW.id);
END
;

Complicated/Simple SQL Insert: adding multiple rows

I have a table connecting principals to their roles. I have come upon a situation where I need to add a role for each user. I have a statement SELECT id FROM principals which grabs a list of all the principals. What I want to create is something like the following:
INSERT INTO role_principal(principal_id,role_id)
VALUES(SELECT id FROM principals, '1');
so for each principal, it creates a new record with a role_id=1. I have very little SQL experience, so I dont know if I can do this as simply as I would like to or if there is some sort of loop feature in SQL that I could use.
Also, this is for a mySQL db (if that matters)
Use VALUES keyword if you want to insert values directly. Omit it to use any SELECT (where column count and type matches) to get the values from.
INSERT INTO role_principal(principal_id,role_id)
(SELECT id, 1 FROM principals);
To avoid duplicates is useful to add a subquery :
INSERT INTO role_principal(principal_id,role_id)
(SELECT id, 1 FROM principals p
WHERE NOT EXISTS
(SELECT * FROM role_principal rp WHERE rp.principal_id=p.id AND role_id=1)
)

SQL INSERT INTO returning autoincrement field

I'm a long time desktop app C++ programmer new to SQL. I need to insert into a table with an autoincrment field, and have that sql statement return the new value for the autoincrement field.
Something LIKE:
INSERT INTO Entrys ('Name','Description')
VALUES ('abc','xyz')
SELECT Entrys.EntryID WHERE EntryID=[THE ONE JUST INSERTED!]
Sorry for being a noob.
Assuming that you're using SQL Server, you can use scope_identity to return "the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch."
INSERT INTO Entrys ('Name','Description') VALUES ('abc','xyz');
SELECT SCOPE_IDENTITY()
select scope_identity
insert into table values ('string value');select scope_identity()
Details here
In SQL Server, you can also use the OUTPUT clause on your INSERT statement:
INSERT INTO Entrys('Name', 'Description')
OUTPUT Inserted.EntryID
VALUES ('abc','xyz')
This will output the newly created IDENTITY field value.
In MySQL you can use LAST_INSERT_ID()
As #marc_s said for SQL Server, in PostgreSQL you can obtain the same behaviour with:
INSERT INTO Entrys ('Name','Description')
VALUES ('abc','xyz')
RETURNING EntryID;
RETURNING is also really useful when you're inserting several tuples and you want all the generated IDs for each of the rows.