Starglazer
Tukijäsen
- Liittynyt
- 17.10.2016
- Viestejä
- 3 236
Totta, kiitos paljon! Huomaa että tarvitse enemmän kokemusta SQL:stä(TUOTE.HINTA = TAULU.MIN)
OR
(TUOTE.HINTA > TAULU.MIN
and TUOTE.HINTA <= TAULU.MAX)
Follow along with the video below to see how to install our site as a web app on your home screen.
Huomio: This feature may not be available in some browsers.
Totta, kiitos paljon! Huomaa että tarvitse enemmän kokemusta SQL:stä(TUOTE.HINTA = TAULU.MIN)
OR
(TUOTE.HINTA > TAULU.MIN
and TUOTE.HINTA <= TAULU.MAX)
Paitsi ettei tämä sittenkään toimi:Totta, kiitos paljon! Huomaa että tarvitse enemmän kokemusta SQL:stä
Paitsi ettei tämä sittenkään toimi:
(TUOTE.HINTA = TAULU.MIN)
OR
(TUOTE.HINTA > TAULU.MIN
and TUOTE.HINTA <= TAULU.MAX)
Jos hinta = 10, kysely palauttaa molemmat rivit.
TUOTE MIN MAX
EKA 5 10
TOKA 10 15
SQL ongelma. Eli mulla on käsissä tyhmästi tehty taulu tähän tyyliin:
TUOTE MIN MAX
EKA 5 10
TOKA 10 15
ja tuossa rajalla katsotaan että arvon 10 tuote kuuluu luokkaan "EKA".
Haen taulusta arvoja näin vertailemalla:
TUOTE.HINTA > TAULU.MIN
and TUOTE.HINTA <= TAULU.MAX
Homma toimii hienosti muuten, mutta aivan alin arvo eli "5" jää pois. Miten tuon saa järkevimmin tehtyä?
SELECT * FROM (
SELECT
TUOTE.ID,
TUOTE.HINTA,
TAULU.TUOTE
FROM TUOTE
JOIN TAULU ON
(TUOTE.HINTA >= TAULU.MIN AND TUOTE.HINTA <= TAULU.MAX)
ORDER BY TAULU.MAX ASC
) AS t
GROUP BY t.ID
Alkuvuodesta löysin kokonaisen sivuston, joka käsitteli nettipalveluiden turvallisuutta kehittäjän näkökulmasta. Siellä oli mm. tarkistuslistoja. Ei tullut laitettua kirjanmerkkeihin ja nyt en enää löydä sitä Tietääkö kukaan mistä sivustosta mahtoi olla kyse?
Juuri tämä. Suurkiitokset!OWASP?
Mistähän syystä tuo Context.Users.Add ei toimi? Kokeilin myös ilman asyncia. Koodi menee tuosta läpi kyllä, mutta mitään muutosta ei tapahdu tuolla tietokannassa..?
Tässä vielä tuo DbContext:
EDIT: Auttoi, kun vaihdoin tuon "using (Context)" => "using (var c= new DatabaseContext())". Miksiköhän ihmeessä? Eikö tuo Context palauta aina uuden DatabaseContext:n, kun siellä (luokassa minkä tuo perii) lukee:
"Context => new DatabaseContext();"
EDIT: Auttoi, kun vaihdoin tuon "using (Context)" => "using (var c= new DatabaseContext())". Miksiköhän ihmeessä? Eikö tuo Context palauta aina uuden DatabaseContext:n, kun siellä (luokassa minkä tuo perii) lukee:
"Context => new DatabaseContext();"
Hmm, otin nuo using-blokit pois ja laitoin vaan pääluokkaan tuon "public DatabaseContext Context => new DatabaseContext();" ja sitten funktioihin suoraan Context:n käytön. Tuli sama virhe kuin aiemmin sillä using (Context) blokilla, eli Add ja Update eivät tee mitään.Juuri noin kuin ississ jo vastasikin. Toi using tyhjentää lopuksi sen contextin. Toinen yrityksesi toimii koska siinä se luodaan aina uudestaan ennen käyttöä. Todennäköisesti tuossa ei kannattaisi käyttää usingia lainkaan, voit käyttää suoraan sitä alkuperäistä Contextia minkä loit.
Do I always have to call Dispose() on my DbContext objects? Nope
for /f "delims=: tokens=2" %%a in ('ipconfig ^| findstr /R /C:"IPv4 Address"') do (set tempip=%%a)
set tempip=%tempip: =%
echo %tempip%
Tuolta löytynee vastaus tähän syntaksiin:Pahoitteluni jos menee väärälle osiolle tai väärään ketjuun:
Koodi:for /f "delims=: tokens=2" %%a in ('ipconfig ^| findstr /R /C:"IPv4 Address"') do (set tempip=%%a) set tempip=%tempip: =% echo %tempip%
Mitä tuo set tempip=%tempip: =% tekee? Tai siis se poistaa välilyönnin ip-osoitteen edestä, sen tiedän mutta miten se tekee sen? Googlella en löytänyt ratkaisua.
Kiitos jo etukäteen vastauksesta.
Tuolta löytynee vastaus tähän syntaksiin:
CMD Variable edit replace - Windows CMD - SS64.com
Aukeaako?
Hmm, otin nuo using-blokit pois ja laitoin vaan pääluokkaan tuon "public DatabaseContext Context => new DatabaseContext();" ja sitten funktioihin suoraan Context:n käytön. Tuli sama virhe kuin aiemmin sillä using (Context) blokilla, eli Add ja Update eivät tee mitään.
npm run startTää on ehkä liian tyhmä kysymys, mutta menkööt.
Mun pitäisi saada windows 10:n käynnistyessä ajettua komentokehotteella tietyssä folderissa komento: npm run start
Ilmeisesti pitäisi tehdä -bat filu, jonka vie windowsin käynnistyksen yhteydessä startattaviin ohjelmiin.
Mutta mikä tuon batch-filun sisältö pitäisi olla, jotta toiveeni toteutuisi?
Ilmeisesti pitäisi tehdä -bat filu, jonka vie windowsin käynnistyksen yhteydessä startattaviin ohjelmiin.
Jos tarkoitus on ajaa yksi ainoa komento kertaalleen koneen käynnistyksen yhteydessä, niin en kyllä ihan heti keksi miksi siitä kannattaisi tehdä yhtään monimutkaisempaa kikkailemalla se palveluksi.Joissain tapauksissa parempi vaihtoehto voi olla ajaa sovellus(ta) Windows-palveluna. Hakukoneeseen how to run(/install) node app as windows service..
Ei siellä batissa tarvitse olla muuta, mutta yleensä alussa laitetaan komentojen kaiutus pois päältä, eli tähän tapaan:okei. Eli käytännössä tuo TheMell:n postaus olisi meikäläisen pelastus.
"npm run start
Vie se sitten siihen kansioon missä haluat ajaa sen komennon ja tee pikakuvake käynnistettäviin ohjelmiin
kun teet tekstieditorilla niin tallenna lainausmerkeissä "npmstart.bat" niin notepad ei tee siitä npmstart.bat.txt"
Siis batin sisällä ei tarvitse olla mitään muuta kuin tuo npm run start komento? Olen dorka jos ja kun en tuota yksinkertaisuutta ymmärtänyt. Ja totta, jos se on siellä kansiossa niin siellähän se sitten ajetaan.
@echo off
npm run start
Noniin. Jatkokysymys jo aiemmin aloitetulle batin tekemiselle, jossa ratkaisu oli siis luoda bat-tiedosto joka ajaa asiansa ja on nyt:
@echo off
npm run start
Milläs ilveellä tuon npm run startin joka avaa erilisenn komentokehotteen auki, saa minimoitua? Nyt prompti aukeaa suoraan näytölle muun oleellisen päälle, joten pitäisi saada jätettyä auki mutta pienennettyä alapalkkiin.
CreateObject("Wscript.Shell").Run "npm run start", 0
Heps kukkuu. @wex , eli tuo 0 jättää kokonaan aukeamatta ruutuun. Tavallaan hyvä, mutta voisi olla näppärämpi tässä skenaariossa että olisi minimoitu vain alapalkkiin. Onko tuohon jokin vaihtoehto. Kyseessä tosiaan win10, ja komentokehotteessa pyörii google assistantin loki sitä mukaa kun jotain tapahtuu tai ei tapahdu. Näppärää olisi, että jos assistant menee mykäksi niin ikkunaa maksimoimalla näkisi mikä error ruudussa on. Muutoin ikkuna saisi olla tosiaan alapalkissa jemmassa, koska lokia ei tarvitse kovinkaan usein käydä vilkuilemassa.
Ihan viestin lopussa olikin sivuhuomiona, että ikkuna on kokonaan piilossa - ja vaihtamalla nollan tilalle kakkosen toimii halutulla tavalla
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': './debug.log',
},
},
'loggers': {
'django.db.backends':{
'handlers': ['file'],
'level': 'DEBUG',
}
},
}
import React from "react";
import "./Form.css";
const Form = props => {
return (
<form onSubmit={props.createNewItem} className="input-form">
<input type="text" name="name" placeholder="name" required />
<input
type="text"
name="description"
placeholder="description"
required
/>
<input type="text" name="comment" placeholder="comment <optional>" />
<div className="form-btns">
<button
onClick={props.clearFields}
className="form-btn btn-disabled"
id="clear-btn"
>
Clear
</button>
<button className="form-btn">Add</button>
</div>
</form>
);
};
export default Form;
Reactin harjoittelua, mutta itse kysymykseen. Miten tuollaisessa funktionaalisessa komponentissa saa inputin valuen selville?
Tarkoituksena muuttaa napin luokkaa riippuen onko kentät tyhjiä vai ei.
const Form = (props) => {}..
const Form = props => {}..
Tuo ei liity mitenkään oikeastaan Reactiin, vaan JavaScriptiin. Nuolisyntaksia käytettäessä, jos funktiolla on vain yksi argumentti, niin sulkuja ei tarvita, muissa tapauksissa tarvitaan.Reactiin ja ylläolevaan kyssäriin liittyen, onko sillä mitään käytännön eroa onko se props suluissa vai ei? Vai onko se tietyissä tilanteissa? Kummastelen vaa ku oon törmännyt muutaman kerran muiden koodissa.
vs.Koodi:const Form = (props) => {}..
Koodi:const Form = props => {}..
// huom sulut pakolliset, vaikka parametrejä on "yksi"
const Form = ({ handleChange, handleSubmit }) => {
// ....
<input onChange={handleChange} ... />
}
// vs.
const Form = props => {
// ....
<input onChange={props.handleChange} ... />
}
// jos tähän lisää uuden, versionhallinta highlightaa vaan lisätyn rivin, versus lisätyn + pilkun lisäämisen
const states = [
'OPEN',
'CLOSED',
'ERROR',
]
const string = 'Marko sanoi: "Hepsan hei"'
// vs.
const string = "Marko sanoi: \"Hepsan hei\""
const foo = ({a, b}) => {...}
Reactiin ja ylläolevaan kyssäriin liittyen, onko sillä mitään käytännön eroa onko se props suluissa vai ei? Vai onko se tietyissä tilanteissa? Kummastelen vaa ku oon törmännyt muutaman kerran muiden koodissa.
vs.Koodi:const Form = (props) => {}..
Koodi:const Form = props => {}..
declare @Avaintable (uusi int, vanha int)
insert into uusitaulu (sarake1, sarake2, sarake3)
output insterted.avain into @Avaintable(uusi)
select tieto1, tieto2, tieto3
from vanhataulu
Juuh elikkäs MS SQL kyssäri vaihteeksi.
Teen tietojen kopioinnin INSERT INTO lausekkeella.
Laitan uudet avaimet talteen output komennolla.
Pitäisi laittaa talteen myös kopioidun rivin avaintieto eli parina pitää nämä uudet ja vanhat avaimet.
Mitenkäs tuo tehdään?
eli vanhan taulun pääavain pitäisi kohdistaa uuden taulun pääavaimeen.Koodi:declare @Avaintable (uusi int, vanha int) insert into uusitaulu (sarake1, sarake2, sarake3) output insterted.avain into @Avaintable(uusi) select tieto1, tieto2, tieto3 from vanhataulu
Taustalla on että pääavaimella kohdistetaan toisessa taulussa tietoja, ja nämäkin tiedot pitää kopioida vanhoilta avaimilta uusille avaimille. Nyt tuo onnistuu avain kerrallaan määrittelemällä alussa kopioitava avain muuttujaan mutta kun näitä kopioitavia avaimia saataa olla useita kymmeniä.
Juuh elikkäs MS SQL kyssäri vaihteeksi.
Teen tietojen kopioinnin INSERT INTO lausekkeella.
Laitan uudet avaimet talteen output komennolla.
Pitäisi laittaa talteen myös kopioidun rivin avaintieto eli parina pitää nämä uudet ja vanhat avaimet.
Mitenkäs tuo tehdään?
eli vanhan taulun pääavain pitäisi kohdistaa uuden taulun pääavaimeen.Koodi:declare @Avaintable (uusi int, vanha int) insert into uusitaulu (sarake1, sarake2, sarake3) output insterted.avain into @Avaintable(uusi) select tieto1, tieto2, tieto3 from vanhataulu
Taustalla on että pääavaimella kohdistetaan toisessa taulussa tietoja, ja nämäkin tiedot pitää kopioida vanhoilta avaimilta uusille avaimille. Nyt tuo onnistuu avain kerrallaan määrittelemällä alussa kopioitava avain muuttujaan mutta kun näitä kopioitavia avaimia saataa olla useita kymmeniä.
Itse taulun sarakkeisiin en kajoa koska tuotantojärjestelmä on kyseessä. Google kuitenkin tuotti tulosta ja sain hoidettua homman kursorilla.Helpommin ja nopeimmin menee kun teet uuteen tauluun kentän sille vanhalle avaimelle.
Eli uusi taulu tyyliin
create tabke uusi (
avain identity,
vanha_avain,
kenttä1,
kenttä2,
jne
)
ja sen jälkeen insert into uusi select avain, kenttä1, kenttä2, jne from vanha;
sitten kun loputkin kohdistukset/muunnokset on tehty niin poistat uudesta taulusta vanha_avain- kentän.
declare @Avaintable (vanha int)
declare @HaettuAvain int
declare kursori cursor fast_forward read_only for select vanha from @Avaintable
insert into @Avaintable
select
avain
from
taulu
open kursori
fetch next from kursori into @HaettuAvain
while @@FETCH_STATUS = 0
begin
... kopioi tiedot sekä siihen liittyvän toisen taulun tiedot ...
fetch next from kursori into @HaettuAvain
end
close kursori
deallocate kursori
Itse taulun sarakkeisiin en kajoa koska tuotantojärjestelmä on kyseessä. Google kuitenkin tuotti tulosta ja sain hoidettua homman kursorilla.
Pseudona suunnilleen näin:
Koodi:declare @Avaintable (vanha int) declare @HaettuAvain int declare kursori cursor fast_forward read_only for select vanha from @Avaintable insert into @Avaintable select avain from taulu open kursori fetch next from kursori into @HaettuAvain while @@FETCH_STATUS = 0 begin ... kopioi tiedot sekä siihen liittyvän toisen taulun tiedot ... fetch next from kursori into @HaettuAvain end close kursori deallocate kursori
No tässä ei ole kyseessä kuin maksimissaan muutama sata riviä niin ei suorituskyvyllä ole kovin isoa merkitystä. Ihan oppimismielessä tämän tein kun SQLlää en ole opetellut ja tässä työssä sitä pääsee näpylöimään. Tämä tietokanta on toimittajan tietokanta ja minä vain lähinnä muuttelen tietoja siellä. Tietokannan ylläpitovastuu on toimittajalla.Voihan sen noinkin tehdä. Tosin rivimäärästä riippuen tuo kursori ja rivi kerrallaan voi olla vähän hidas.
Jos rakenteisiin ei saa koskea ja rivejä on paljon niin tekisin edelleen alkuperäisellä tavalla mutta tulokset ensin temp- tauluun ja sieltä viralliseen uuteen identity_insert päällä jolloin riveille ei enää luoda uusia avaimia syötettäessä viralliseen. Lopuksi temp- taulun poisto.
Harvoin on tullut vastaan niin tiukkoja järjestelmiä ettei datamigraation aikana ole saanut tehdä uusia rakenteita kantaan
No tässä ei ole kyseessä kuin maksimissaan muutama sata riviä niin ei suorituskyvyllä ole kovin isoa merkitystä. Ihan oppimismielessä tämän tein kun SQLlää en ole opetellut ja tässä työssä sitä pääsee näpylöimään. Tämä tietokanta on toimittajan tietokanta ja minä vain lähinnä muuttelen tietoja siellä. Tietokannan ylläpitovastuu on toimittajalla.
Mitä tässä parin vuoden aikana olen opiskellut samalla SQL kieltä niin onhan tuo aivan älyttömän monipuolinen kieli.
No tämä kursori ei ehdi kauaa olla olemassa niin jos selviäisin ilman huutoa Tuo nyt oli ensimmäinen toteutus minkä sain toimimaan ilman tietokannan rakenteeseen kajoamista. SQL osaamiseni ei ole vielä kovin kaksista.OT: Eräs vanha pomoni sanoi, että tulee lyömään minua, jos laitan vielä tuotantokantaan kursoreita. En sitten laittanut, niin en tiedä, olisiko hakkaamisia tapahtunut..
Niiden suorituskyky on oikeassa käytössä karmea, luettavuus huono ja ne voi aina korvata paremmalla ratkaisulla. Esim. tietokannan käyminen läpi kaksi kertaa on parempi ratkaisu. Siis vaikka niin, että tehdään tuo temppitaulu ensin ja sen avulla hoidetaan homma toisella iteraatiolla.
declare @Avaintable (vanha int)
declare @HaettuAvain int
declare @Rivimaara
declare
insert into @Avaintable
select
avain
from
taulu
set @Rivimaara= (select count(*) from @Avaintable)
begin
while rivi < @Rivimaara
set @Haettuavain = @Avaintable(vanha) rivi?
... kopioi tiedot sekä siihen liittyvän toisen taulun tiedot ...
rivi = rivi +1
end
Niin muuten, miten tuo sama tehdään käytännössä while loopilla? Jostain syystä en löytänyt selkeää esimerkkiä? Eli tallennan vaikka 5 tietuetta väliaikaiseen tauluun, miten käyn ne läpi while loopissa?
Koodi:declare @Avaintable (vanha int) declare @HaettuAvain int declare @Rivimaara declare insert into @Avaintable select avain from taulu set @Rivimaara= (select count(*) from @Avaintable) begin while rivi < @Rivimaara set @Haettuavain = @Avaintable(vanha) rivi? ... kopioi tiedot sekä siihen liittyvän toisen taulun tiedot ... rivi = rivi +1 end
Mulla pyörii Herokussa Node/React-sovellus. Sovelluksen pyörittämiseen liittyy pari päivittäin ajettavaa node-skriptiä. Saan ajastettua skriptien ajamisen Heroku Scheduler -addonilla, mutta ongelma on se, että en näe skriptien ajosta mitään ajon aloituksen ja loppumisen lisäksi mitään logeja. Mulla on molemmista skripteissä paljon console.logeja / console.erroreita ja oletin, että ne tulostuisi Herokun logeihin.
Näin ei kuitenkaan ole. Skriptit eivät ole osa sovellusta, joten niiden logit eivät tulostu. Herokun logiin tulostuu ainoastaan sovelluksen sisäiset logit. Onko tähän olemassa mitään helppoa ratkaisua? Logitiedot ovat tärkeitä sovelluksen pyörimisen kannalta.
En tsekannut. Olin ajellut noita skriptejä vain manuaalisesti konsolista ja silloin logit ei tulostu. Nyt tein testin ihan tuolla schedulerilla ja silloin logit tulostuu. Eli ongelmaa ei siis edes ole.Tsekkasitko ohjeet: Heroku Scheduler | Heroku Dev Center