SQL Anywhere autoincrement reset - auto-increment

I've got a SQL Anywhere 9 database, and I would like to reset the autoincrement value on one of my columns to a specific number.
I guess I need the SQL-Anywhere equivalent of:
ALTER TABLE foo AUTO_INCREMENT =100

Just so the answer is actually here, not just linked to:
Use the sa_reset_identity system procedure:
sa_reset_identity (
[ table_name
[, owner
[, new_identity_value ] ] ]
)

A google search turned up this. I have never used SQL Anywhere, so I'm afraid I can't help anymore.

The correct system procedure is sa_reset_identity
CALL sa_reset_identity('table_name', 'user_name', new_start_value -1);
For example, you have a table called CITIES, a user DBA and you want the autoincrement to start with value 1. Your code would be:
CALL sa_reset_identity('cities', 'DBA', 0);
Source: http://www.sqlines.com/sybase-asa/autoincrement_identity

Related

Codeigniter 4 multiple database tables in 1 model file

I have 1 database and inside there are maybe say 3 tables, users, user_profile, user_stats. I would like to ask is it possible to have these 3 tables in 1 model file? If user were to visit User A profile, it will show all the User A records from these 3 tables. I can't find it anywhere whether is it possible in CI4. Hope someone here can guide me on this. Thanks in advance guys!
You will need to override the find method. I have done it for findAll and haven't tried for find a method. So you may need to improvise on the following logic. There are three places where based on the condition we are fetching the rows, one check for the array, another for a single row, and last is the default one. So you will need to modify this behavior.
Replace :
$row = $builder
With your custom builder query such as following:
$row = $builder->select("users.*");
$builder->join('user_profile', 'user_profile.id = users.id','inner');
$builder->join('user_stats', 'user_stats.id = users.id','inner');
->whereIn($this->table . '.' . $this->primaryKey, $id)
->get();
You will need to replace the last query according to the conditions in find method and also instead of mentioning users explicitly you should use $this->table and similar for the primary key instead of id, you should use $this->primaryKey.

Is there any alternative of CREATE TYPE in SQL as CREATE TYPE is Not supported in Azure SQL data warehouse

I am trying to execute this query but as userdefined(Create type) types are not supportable in azure data warehouse. and i want to use it in stored procedure.
CREATE TYPE DataTypeforCustomerTable AS TABLE(
PersonID int,
Name varchar(255),
LastModifytime datetime
);
GO
CREATE PROCEDURE usp_upsert_customer_table #customer_table DataTypeforCustomerTable READONLY
AS
BEGIN
MERGE customer_table AS target
USING #customer_table AS source
ON (target.PersonID = source.PersonID)
WHEN MATCHED THEN
UPDATE SET Name = source.Name,LastModifytime = source.LastModifytime
WHEN NOT MATCHED THEN
INSERT (PersonID, Name, LastModifytime)
VALUES (source.PersonID, source.Name, source.LastModifytime);
END
GO
CREATE TYPE DataTypeforProjectTable AS TABLE(
Project varchar(255),
Creationtime datetime
);
GO
CREATE PROCEDURE usp_upsert_project_table #project_table DataTypeforProjectTable READONLY
AS
BEGIN
MERGE project_table AS target
USING #project_table AS source
ON (target.Project = source.Project)
WHEN MATCHED THEN
UPDATE SET Creationtime = source.Creationtime
WHEN NOT MATCHED THEN
INSERT (Project, Creationtime)
VALUES (source.Project, source.Creationtime);
END
Is there any alternative way to do this.
You've got a few challenges there, because most of what you're trying to convert is not the way to do things on ASDW.
First, as you point out, CREATE TYPE is not supported, and there is no equivalent alternative.
Next, the code appears to be doing single inserts to a table. That's really bad on ASDW, performance will be dreadful.
Next, there's no MERGE statement (yet) for ASDW. That's because UPDATE is not the best way to handle changing data.
And last, stored procedures work a little differently on ASDW, they're not compiled, but interpreted each time the procedure is called. Stored procedures are great for big chunks of table-level logic, but not recommended for high volume calls with single-row operations.
I'd need to know more about the use case to make specific recommendations, but in general you need to think in tables rather than rows. In particular, focus on the CREATE TABLE AS (CTAS) way of handling your ELT.
Here's a good link, it shows how the equivalent of a Merge/Upsert can be handled using a CTAS:
https://learn.microsoft.com/en-us/azure/sql-data-warehouse/sql-data-warehouse-develop-ctas#replace-merge-statements
As you'll see, it processes two tables at a time, rather than one row. This means you'll need to review the logic that called your stored procedure example.
If you get your head around doing everything in CTAS, and separately around Distribution, you're well on your way to having a high performance data warehouse.
Temp tables in Azure SQL Data Warehouse have a slightly different behaviour to box product SQL Server or Azure SQL Database - they exist at the session level. So all you have to do is convert your CREATE TYPE statements to temp tables and split the MERGE out into separate INSERT / UPDATE / DELETE statements as required.
Example:
CREATE TABLE #DataTypeforCustomerTable (
PersonID INT,
Name VARCHAR(255),
LastModifytime DATETIME
)
WITH
(
DISTRIBUTION = HASH( PersonID ),
HEAP
)
GO
CREATE PROCEDURE usp_upsert_customer_table
AS
BEGIN
-- Add records which do not already exist
INSERT INTO customer_table ( PersonID, Name, LastModifytime )
SELECT PersonID, Name, LastModifytime
FROM #DataTypeforCustomerTable AS source
WHERE NOT EXISTS
(
SELECT *
FROM customer_table target
WHERE source.PersonID = target.PersonID
)
...
Simply load the temp table and execute the stored proc. See here for more details on temp table scope.
If you are altering a large portion of the table then you should consider the CTAS approach to create a new table, then rename it as suggested by Ron.

How do I specify a primary key on table creation with haskellDB?

Currently I am using something like this:
dbCreateTable db "MyTable" [ ("Col1", (StringT, False)), ("Col2", (StringT, False)) ]
which works fine, but i'd like to make "Col1" the primary key. Do i need to go back to raw SQL?
edit:
This still seems to hold:
"The part of creating a database from Haskell itself is not very
useful, for example you cannot express foreign- and primary keys,
indexes and constraints. Even the most simple database will need
one of these."
From http://www.mijnadres.net/published/HaskellDB.pdf
As the edit notes, HaskellDB is not very good at creating tables at the moment. It's best to build a database first, and then extract the info.

Astyanax key range query

trying to write a query which will paginate through all rows in a column family using astyanax client and RowSliceQuery.
keyspace.prepareQuery(COLUMN_FAMILY).getKeyRange(null, null, null, null, 100);
Done this successfully using hector where 1st call is done with null start and end keys. After retrieving 1st page I use last key from the result to make query for second page and etc. This is code for 1st page using hector.
HFactory.createRangeSlicesQuery(keyspace,
LongSerializer.get(), new CompositeSerializer(),
BytesArraySerializer.get())
.setColumnFamily(COLUMN_FAMILY)
.setRange(null, null, false, 100).setRowCount(100);
Now when I am trying to do this with astyanax I am getting errors about null and non-null keys and tokens. Not sure what tokens do in this query. Also I am able to use allRows(), but would like to do this using key range query as it gives me more flexibility.
Does anybody have an example of key range query using astyanax? I cannot find an example neither in "getting started" documentation or anywhere else on the net.
Thanks!
Anton
What you are referring to is the getRowRange method:
keyspace.prepareQuery(CF_STANDARD1)
.getRowRange(startKey, endKey, startToken, endToken, count)
Note however that this works only when the ByteOrderedPartitioner is used. Since by default Cassandra uses the Murmur3Partitioner, this will usually not work. Using an index to do this instead is recommended. Astyanax also provides the reverse index search recipe which takes advantage of a second column family which stores your keys as columns to allow efficient range searches on the original data.
Check this sample code. I hope this code will help you in doing the paging.
IndexQuery<String, String> query = keyspace
.prepareQuery(CF_STANDARD1).searchWithIndex()
.setRowLimit(10).autoPaginateRows(true).addExpression()
.whereColumn("Index2").equals().value(42);
Best,

how SQL injection is done? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
XKCD SQL injection - please explain
What is the general concept behind sql injection ?
Being a rails developer
This is unsafe
Booking.find(:all, :conditions => [ 'bookings.user_id = #{params[user_id]]}'] )
and this is safe:--
Booking.find(:all, :conditions => [ 'bookings.user_id = ?', params[user_id]] )
am i right?
So my question is how the sql injection is done?
How those guys do some stuff like that. Any live example/ tutorial where somebody is showing this kind of stuff. Anything basic for knowing the logic.
SQL Injection happens when a programmer gets lazy. A vulnerable query would look like this:
DECLARE #cmd varchar(256)
SET cmd='SELECT #col FROM Table'
EXEC #cmd
With #col being a variable passed into a stored procedure.
Usually, the user would enter a column in that already exists for that variable. But a more devious user could enter something like this:
* FROM Table; DROP DATABASE data;--
The * FROM Table; finishes off the previous statement. Then, DROP DATABASE data; is the payload that does bad things, in this case, dropping the database. Finally, the -- comments out the rest of the query so it doesn't get any errors from the injection.
So, instead of executing this:
SELECT column
FROM Table
You get this:
SELECT *
FROM Table;
DROP DATABASE data;
--
Which is not good.
And this:
All the user has to do is enter:
1234; DROP TABLE BOOKINGS
...
I don't know about rails, but by doing this Booking.find(:all, :conditions => [ 'bookings.user_id = #{params[user_id]]}'] ), you risk that the user give to user_id the value 1 OR 1=1 and as you can see, it will modify your request.
With more injection you could do something like 1; DROP TABLE BOOKINGS etc.
Basically injection is just "hijacking" a basic request to add yours.
Bobby tables
If you have a simple query like
SELECT * FROM bookings WHERE user_id = ORDER BY user_id ASC;
if you don't check user id, it can close your query, then start a new (harmful one) and discard the rest. To achieve this, generally, you would enter something like
1; DELETE FROM bookings; --
initial ; closes the good query, the bad query comes next, then it is closed with ; and -- makes sure that anything that would come next in the good query is commented out. You then end up with
SELECT * FROM bookings WHERE user_id = 1; DELETE FROM bookings; -- ORDER BY user_id ASC;
If your data in properly cleaned and sanatized, a user can try to get their own SQL code to run on the server. for example, let's say you have a query like this:
"SELECT * FROM products WHERE product_type = $type"
where type is unchanged user input from a text field. now, if I were to search for this type:
(DELETE FROM products)
You are gonna be in a world of hurt. This is why it's important to make sure all user input in sanatized before running it in the DB.
Plenty of excellent papers on the theory of SQL injection here:
sql injection filetype:pdf
Should be easy enough to hunt one down that is specific to your language/DB combination.

Resources